From 367e678ff91d2df2ac1ab4ccb532937da4f7b109 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Fri, 24 Jul 2009 13:14:51 +0000 Subject: [PATCH] User management by profile moving forward: pages to check the projection of objects/users in user defined dimensions Introduced parameters in OQL (:myvar) Added the verb MetaModel::IsValidObject($oMyObj) SVN:code[88] --- .../userrightsprofile.class.inc.php | 201 ++-- trunk/business/itop.business.class.inc.php | 2 + trunk/core/config.class.inc.php | 2 +- trunk/core/coreexception.class.inc.php | 4 +- trunk/core/dbobjectsearch.class.php | 17 +- trunk/core/dbobjectset.class.php | 7 +- trunk/core/expression.class.inc.php | 65 +- trunk/core/metamodel.class.php | 32 +- trunk/core/oql/oql-lexer.php | 106 +- trunk/core/oql/oql-lexer.plex | 10 +- trunk/core/oql/oql-parser.php | 956 +++++++++--------- trunk/core/oql/oql-parser.y | 17 +- trunk/core/oql/oqlinterpreter.class.inc.php | 18 +- trunk/core/oql/oqlquery.class.inc.php | 58 +- trunk/core/sqlquery.class.inc.php | 11 +- trunk/core/valuesetdef.class.inc.php | 44 +- trunk/pages/testlist.inc.php | 4 +- trunk/pages/usermanagement_classproj.php | 90 ++ trunk/pages/usermanagement_profileproj.php | 100 ++ 19 files changed, 1107 insertions(+), 637 deletions(-) create mode 100644 trunk/pages/usermanagement_classproj.php create mode 100644 trunk/pages/usermanagement_profileproj.php diff --git a/trunk/addons/userrights/userrightsprofile.class.inc.php b/trunk/addons/userrights/userrightsprofile.class.inc.php index 3fd9c9f24..7b72df453 100644 --- a/trunk/addons/userrights/userrightsprofile.class.inc.php +++ b/trunk/addons/userrights/userrightsprofile.class.inc.php @@ -98,10 +98,81 @@ class URP_Dimensions extends DBObject //MetaModel::Init_InheritAttributes(); MetaModel::Init_AddAttribute(new AttributeString("name", array("label"=>"name", "description"=>"label", "allowed_values"=>null, "sql"=>"name", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("description", array("label"=>"description", "description"=>"one line description", "allowed_values"=>null, "sql"=>"description", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeString("type", array("label"=>"type", "description"=>"class name or data type (projection unit)", "allowed_values"=>new ValueSetEnumClasses('bizmodel', 'String,Integer'), "sql"=>"type", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); //MetaModel::Init_InheritFilters(); MetaModel::Init_AddFilterFromAttribute("name"); MetaModel::Init_AddFilterFromAttribute("description"); + MetaModel::Init_AddFilterFromAttribute("type"); + } + + public function CheckProjectionSpec($oProjectionSpec) + { + $sExpression = $oProjectionSpec->Get('value'); + $sAttribute = $oProjectionSpec->Get('attribute'); + + // Shortcut: "any value" or "no value" means no projection + if (empty($sExpression)) return; + if ($sExpression == '') return; + + // 1st - compute the data type for the dimension + // + $sType = $this->Get('type'); + if (MetaModel::IsValidClass($sType)) + { + $sExpectedType = $sType; + } + else + { + $sExpectedType = '_scalar_'; + } + + // 2nd - compute the data type for the projection + // + $bIsOql = true; + $sExpressionClass = ''; + try + { + $oObjectSearch = DBObjectSearch::FromOQL($sExpression); + $sExpressionClass = $oObjectSearch->GetClass(); + } + catch (OqlException $e) + { + $bIsOql = false; + } + if ($bIsOql) + { + if (empty($sAttribute)) + { + $sFoundType = $sExpressionClass; + } + else + { + if (!MetaModel::IsValidAttCode($sExpressionClass, $sAttribute)) + { + throw new CoreException('Unkown attribute code in projection specification', array('found' => $sAttribute, 'expecting' => MetaModel::GetAttributesList($sExpressionClass), 'class' => $sExpressionClass, 'projection' => $oProjectionSpec)); + } + $oAttDef = MetaModel::GetAttributeDef($sExpressionClass, $sAttribute); + if ($oAttDef->IsExternalKey()) + { + $sFoundType = $oAttDef->GetTargetClass(); + } + else + { + $sFoundType = '_scalar_'; + } + } + } + else + { + $sFoundType = '_scalar_'; + } + + // Compare the dimension type and projection type + if ($sFoundType != $sExpectedType) + { + throw new CoreException('Wrong type in projection specification', array('found' => $sFoundType, 'expecting' => $sExpectedType, 'expression' => $sExpression, 'attribute' => $sAttribute, 'projection' => $oProjectionSpec)); + } } } @@ -163,7 +234,8 @@ class URP_ProfileProjection extends DBObject MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "label"=>"profile", "description"=>"usage profile", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("label"=>"Profile", "description"=>"Profile name", "allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name"))); - MetaModel::Init_AddAttribute(new AttributeString("value", array("label"=>"Value expression", "description"=>"OQL expression (using \$user) | constant", "allowed_values"=>null, "sql"=>"value", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeString("value", array("label"=>"Value expression", "description"=>"OQL expression (using \$user) | constant | ", "allowed_values"=>null, "sql"=>"value", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeString("attribute", array("label"=>"Attribute", "description"=>"Target attribute code (optional)", "allowed_values"=>null, "sql"=>"attribute", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); //MetaModel::Init_InheritFilters(); MetaModel::Init_AddFilterFromAttribute("dimensionid"); @@ -172,7 +244,25 @@ class URP_ProfileProjection extends DBObject public function ProjectUser(URP_Users $oUser) { - // #@# to be implemented + $sExpr = $this->Get('value'); + if (preg_match('/^\s*([a-zA-Z0-9;]+)\s*$/', $sExpr, $aMatches)) + { + // Constant value(s) + $aRes = explode(';', $aMatches[1]); + } + elseif ($sExpr == '') + { + $aRes = array(''); + } + else + { + $sColumn = $this->Get('attribute'); + // SELECT... + $oValueSetDef = new ValueSetObjects($sExpr, $sColumn); + $aValues = $oValueSetDef->GetValues(array('user' => $oUser), ''); + $aRes = array_values($aValues); + } + return $aRes; } } @@ -201,29 +291,53 @@ class URP_ClassProjection extends DBObject MetaModel::Init_AddAttribute(new AttributeString("class", array("label"=>"Class", "description"=>"Target class", "allowed_values"=>null, "sql"=>"class", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeString("value", array("label"=>"Value expression", "description"=>"OQL expression (using \$this) | constant", "allowed_values"=>null, "sql"=>"value", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeString("value", array("label"=>"Value expression", "description"=>"OQL expression (using \$this) | constant | ", "allowed_values"=>null, "sql"=>"value", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeString("attribute", array("label"=>"Attribute", "description"=>"Target attribute code (optional)", "allowed_values"=>null, "sql"=>"attribute", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); //MetaModel::Init_InheritFilters(); MetaModel::Init_AddFilterFromAttribute("dimensionid"); MetaModel::Init_AddFilterFromAttribute("class"); } + + public function ProjectObject($oObject) + { + $sExpr = $this->Get('value'); + if (preg_match('/^\s*([a-zA-Z0-9;]+)\s*$/', $sExpr, $aMatches)) + { + // Constant value(s) + $aRes = explode(';', $aMatches[1]); + } + elseif ($sExpr == '') + { + $aRes = array(''); + } + else + { + $sColumn = $this->Get('attribute'); + // SELECT... + $oValueSetDef = new ValueSetObjects($sExpr, $sColumn); + $aValues = $oValueSetDef->GetValues(array('this' => $oObject), ''); + $aRes = array_values($aValues); + } + return $aRes; + } } -class URP_ClassGrant extends DBObject +class URP_ActionGrant extends DBObject { public static function Init() { $aParams = array ( "category" => "addon/userrights", - "name" => "class_permission", + "name" => "action_permission", "description" => "permissions on classes", "key_type" => "autoincrement", "key_label" => "", "name_attcode" => "", "state_attcode" => "", "reconc_keys" => array(), - "db_table" => "priv_urp_grant_classes", + "db_table" => "priv_urp_grant_actions", "db_key_field" => "id", "db_finalclass_field" => "", ); @@ -308,23 +422,12 @@ class URP_AttributeGrant extends DBObject MetaModel::Init_Params($aParams); //MetaModel::Init_InheritAttributes(); - // Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked) - MetaModel::Init_AddAttribute(new AttributeExternalKey("profileid", array("targetclass"=>"URP_Profiles", "jointype"=> "", "label"=>"Profile", "description"=>"usage profile", "allowed_values"=>null, "sql"=>"profileid", "is_null_allowed"=>false, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeExternalField("profile", array("label"=>"Profile", "description"=>"usage profile", "allowed_values"=>null, "extkey_attcode"=> 'profileid', "target_attcode"=>"name"))); - MetaModel::Init_AddAttribute(new AttributeString("class", array("label"=>"class", "description"=>"class name", "allowed_values"=>null, "sql"=>"class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeEnum("permission", array("label"=>"permission", "description"=>"allowed or not allowed?", "allowed_values"=>new ValueSetEnum('yes,no'), "sql"=>"permission", "default_value"=>"yes", "is_null_allowed"=>false, "depends_on"=>array()))); - + MetaModel::Init_AddAttribute(new AttributeExternalKey("actiongrantid", array("targetclass"=>"URP_ActionGrant", "jointype"=> "", "label"=>"Action grant", "description"=>"action grant", "allowed_values"=>null, "sql"=>"actiongrantid", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("attcode", array("label"=>"attribute", "description"=>"attribute code", "allowed_values"=>null, "sql"=>"attcode", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array()))); - MetaModel::Init_AddAttribute(new AttributeString("action", array("label"=>"action", "description"=>"operations to perform on the given class", "allowed_values"=>null, "sql"=>"action", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); //MetaModel::Init_InheritFilters(); - // Common to all grant classes (could be factorized by class inheritence, but this has to be benchmarked) - MetaModel::Init_AddFilterFromAttribute("profileid"); - MetaModel::Init_AddFilterFromAttribute("profile"); - MetaModel::Init_AddFilterFromAttribute("class"); - + MetaModel::Init_AddFilterFromAttribute("actiongrantid"); MetaModel::Init_AddFilterFromAttribute("attcode"); - MetaModel::Init_AddFilterFromAttribute("action"); } } @@ -454,18 +557,18 @@ class UserRightsProfile extends UserRightsAddOnAPI } else { - $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ClassGrant WHERE class = '$sClass' AND action = '$sAction' AND profileid = $iProfileId")); + $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ActionGrant WHERE class = '$sClass' AND action = '$sAction' AND profileid = $iProfileId")); $bAddCell = ($oSet->Count() < 1); } if ($bAddCell) { // Create a new entry - $oMyClassGrant = MetaModel::NewObject("URP_ClassGrant"); - $oMyClassGrant->Set("profileid", $iProfileId); - $oMyClassGrant->Set("class", $sClass); - $oMyClassGrant->Set("action", $sAction); - $oMyClassGrant->Set("permission", "yes"); - $iId = $oMyClassGrant->DBInsertNoReload(); + $oMyActionGrant = MetaModel::NewObject("URP_ActionGrant"); + $oMyActionGrant->Set("profileid", $iProfileId); + $oMyActionGrant->Set("class", $sClass); + $oMyActionGrant->Set("action", $sAction); + $oMyActionGrant->Set("permission", "yes"); + $iId = $oMyActionGrant->DBInsertNoReload(); } } foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus) @@ -482,38 +585,12 @@ class UserRightsProfile extends UserRightsAddOnAPI if ($bAddCell) { // Create a new entry - $oMyClassGrant = MetaModel::NewObject("URP_StimulusGrant"); - $oMyClassGrant->Set("profileid", $iProfileId); - $oMyClassGrant->Set("class", $sClass); - $oMyClassGrant->Set("stimulus", $sStimulusCode); - $oMyClassGrant->Set("permission", "yes"); - $iId = $oMyClassGrant->DBInsertNoReload(); - } - } - foreach (MetaModel::GetAttributesList($sClass) as $sAttCode) - { - if ($bNewProfile) - { - $bAddCell = true; - } - else - { - $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_AttributeGrant WHERE class = '$sClass' AND attcode = '$sAttCode' AND profileid = $iProfileId")); - $bAddCell = ($oSet->Count() < 1); - } - if ($bAddCell) - { - foreach (array('read', 'modify') as $sAction) - { - // Create a new entry - $oMyAttGrant = MetaModel::NewObject("URP_AttributeGrant"); - $oMyAttGrant->Set("profileid", $iProfileId); - $oMyAttGrant->Set("class", $sClass); - $oMyAttGrant->Set("attcode", $sAttCode); - $oMyAttGrant->Set("action", $sAction); - $oMyAttGrant->Set("permission", "yes"); - $iId = $oMyAttGrant->DBInsertNoReload(); - } + $oMyStGrant = MetaModel::NewObject("URP_StimulusGrant"); + $oMyStGrant->Set("profileid", $iProfileId); + $oMyStGrant->Set("class", $sClass); + $oMyStGrant->Set("stimulus", $sStimulusCode); + $oMyStGrant->Set("permission", "yes"); + $iId = $oMyStGrant->DBInsertNoReload(); } } } @@ -577,13 +654,15 @@ class UserRightsProfile extends UserRightsAddOnAPI public function IsActionAllowed($sUserName, $sClass, $iActionCode, dbObjectSet $aInstances) { + // #@# temporary + return true; if (!array_key_exists($iActionCode, self::$m_aActionCodes)) { return UR_ALLOWED_NO; } $sAction = self::$m_aActionCodes[$iActionCode]; - $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ClassGrant WHERE class = '$sClass' AND action = '$sAction' AND login = '$sUserName'")); + $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ActionGrant WHERE class = '$sClass' AND action = '$sAction' AND login = '$sUserName'")); if ($oSet->Count() < 1) { return UR_ALLOWED_NO; @@ -605,6 +684,8 @@ class UserRightsProfile extends UserRightsAddOnAPI public function IsActionAllowedOnAttribute($sUserName, $sClass, $sAttCode, $iActionCode, dbObjectSet $aInstances) { + // #@# temporary + return true; if (!array_key_exists($iActionCode, self::$m_aActionCodes)) { return UR_ALLOWED_NO; @@ -633,6 +714,8 @@ class UserRightsProfile extends UserRightsAddOnAPI public function IsStimulusAllowed($sUserName, $sClass, $sStimulusCode, dbObjectSet $aInstances) { + // #@# temporary + return true; $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_StimulusGrant WHERE class = '$sClass' AND stimulus = '$sStimulusCode' AND login = '$sUserName'")); if ($oSet->Count() < 1) { diff --git a/trunk/business/itop.business.class.inc.php b/trunk/business/itop.business.class.inc.php index f4ca40d13..dcad88f70 100644 --- a/trunk/business/itop.business.class.inc.php +++ b/trunk/business/itop.business.class.inc.php @@ -260,6 +260,8 @@ class bizPerson extends bizContact MetaModel::Init_AddAttribute(new AttributeString("first_name", array("label"=>"first Name", "description"=>"First name", "allowed_values"=>null, "sql"=>"first_name", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("employe_number", array("label"=>"Employe Number", "description"=>"employe number", "allowed_values"=>null, "sql"=>"employe_number", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeExternalKey("login_id", array("targetclass"=>"URP_Users", "label"=>"Login", "description"=>"Login information", "allowed_values"=>null, "sql"=>"login_id", "is_null_allowed"=>true, "depends_on"=>array()))); + MetaModel::Init_InheritFilters(); MetaModel::Init_AddFilterFromAttribute("first_name"); MetaModel::Init_AddFilterFromAttribute("employe_number"); diff --git a/trunk/core/config.class.inc.php b/trunk/core/config.class.inc.php index 94bfe8717..c18c716ff 100644 --- a/trunk/core/config.class.inc.php +++ b/trunk/core/config.class.inc.php @@ -256,7 +256,7 @@ class Config fwrite($hFile, "\t\t// to be continued...\n"); fwrite($hFile, "\t),\n"); fwrite($hFile, "\t'addons' => array (\n"); - fwrite($hFile, "\t\t'user rights' => '../addons/userrights/userrightsmatrix.class.inc.php',\n"); + fwrite($hFile, "\t\t'user rights' => '../addons/userrights/userrightsprofile.class.inc.php',\n"); fwrite($hFile, "\t\t// other modules to come later\n"); fwrite($hFile, "\t)\n"); fwrite($hFile, ");\n"); diff --git a/trunk/core/coreexception.class.inc.php b/trunk/core/coreexception.class.inc.php index eb5ae8b9d..a31f87d66 100644 --- a/trunk/core/coreexception.class.inc.php +++ b/trunk/core/coreexception.class.inc.php @@ -23,11 +23,11 @@ class CoreException extends Exception { if (is_array($val)) { - $aPairs[$key] = '('.implode(', ', $val).')'; + $aPairs[] = $key.'=>('.implode(', ', $val).')'; } else { - $aPairs[$key] = $val; + $aPairs[] = $key.'=>'.$val; } } $sValue = '{'.implode('; ', $aPairs).'}'; diff --git a/trunk/core/dbobjectsearch.class.php b/trunk/core/dbobjectsearch.class.php index 86d6e057a..236a0b721 100644 --- a/trunk/core/dbobjectsearch.class.php +++ b/trunk/core/dbobjectsearch.class.php @@ -662,7 +662,7 @@ class DBObjectSearch } if (count($aParams) > 0) { - throw new CoreException("Unused parameter(s) for this SibusQL expression: (".implode(', ', array_keys($aParams)).")"); +// throw new CoreException("Unused parameter(s) for this SibusQL expression: (".implode(', ', array_keys($aParams)).")"); } return $sQuery; } @@ -736,6 +736,10 @@ class DBObjectSearch return new FieldExpression($sFltCode, $sClassAlias); } + elseif ($oExpression instanceof VariableOqlExpression) + { + return new VariableExpression($oExpression->GetName()); + } elseif ($oExpression instanceof TrueOqlExpression) { return new TrueExpression; @@ -763,7 +767,7 @@ class DBObjectSearch if (empty($sQuery)) return null; $oOql = new OqlInterpreter($sQuery); - $oOqlQuery = $oOql->ParseQuery(); + $oOqlQuery = $oOql->ParseObjectQuery(); $sClass = $oOqlQuery->GetClass(); $sClassAlias = $oOqlQuery->GetClassAlias(); @@ -860,13 +864,14 @@ class DBObjectSearch if (empty($sQuery)) return null; $sQuery = self::privProcessParams($sQuery, $aParams, $oObject); + if (preg_match('@^\\s*SELECT@', $sQuery)) + { + return self::FromOQL($sQuery, $aParams, $oObject); + } + $iSepPos = strpos($sQuery, ":"); if ($iSepPos === false) { - if (preg_match('@^\\s*SELECT@', $sQuery)) - { - return self::FromOQL($sQuery, $aParams, $oObject); - } // Only the class was specified -> all rows are required $sClass = trim($sQuery); $oFilter = new DBObjectSearch($sClass); diff --git a/trunk/core/dbobjectset.class.php b/trunk/core/dbobjectset.class.php index d2719c5cd..9e6cf5459 100644 --- a/trunk/core/dbobjectset.class.php +++ b/trunk/core/dbobjectset.class.php @@ -21,10 +21,11 @@ class DBObjectSet private $m_aId2Row; private $m_iCurrRow; - public function __construct($oFilter, $aOrderBy = array()) + public function __construct($oFilter, $aOrderBy = array(), $aArgs = array()) { $this->m_oFilter = $oFilter; $this->m_aOrderBy = $aOrderBy; + $this->m_aArgs = $aArgs; $this->m_bLoaded = false; $this->m_aData = array(); @@ -109,8 +110,8 @@ class DBObjectSet public function Load() { if ($this->m_bLoaded) return; -// #@# debug - echo "Loading (".$this->m_oFilter->ToSibuSQL().")....
\n"; - $sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, $this->m_aOrderBy); + + $sSQL = MetaModel::MakeSelectQuery($this->m_oFilter, $this->m_aOrderBy, $this->m_aArgs); $resQuery = CMDBSource::Query($sSQL); if (!$resQuery) return; diff --git a/trunk/core/expression.class.inc.php b/trunk/core/expression.class.inc.php index 76409cdc1..f2646802e 100644 --- a/trunk/core/expression.class.inc.php +++ b/trunk/core/expression.class.inc.php @@ -17,7 +17,7 @@ abstract class Expression abstract public function Translate($aTranslationData, $bMatchAll = true); // recursive rendering - abstract public function Render(); + abstract public function Render($aArgs = array()); // recursively builds an array of class => fieldname abstract public function ListRequiredFields(); @@ -119,11 +119,11 @@ class BinaryExpression extends Expression } // recursive rendering - public function Render() + public function Render($aArgs = array()) { $sOperator = $this->GetOperator(); - $sLeft = $this->GetLeftExpr()->Render(); - $sRight = $this->GetRightExpr()->Render(); + $sLeft = $this->GetLeftExpr()->Render($aArgs); + $sRight = $this->GetRightExpr()->Render($aArgs); return "($sLeft $sOperator $sRight)"; } @@ -164,7 +164,7 @@ class UnaryExpression extends Expression } // recursive rendering - public function Render() + public function Render($aArgs = array()) { return CMDBSource::Quote($this->m_value); } @@ -228,7 +228,7 @@ class FieldExpression extends UnaryExpression public function GetName() {return $this->m_sName;} // recursive rendering - public function Render() + public function Render($aArgs = array()) { if (empty($this->m_sParent)) { @@ -270,6 +270,43 @@ class FieldExpression extends UnaryExpression } +class VariableExpression extends UnaryExpression +{ + protected $m_sName; + + public function __construct($sName) + { + parent::__construct($sName); + + $this->m_sName = $sName; + } + + public function IsTrue() + { + // return true if we are certain that it will be true + return false; + } + + public function GetName() {return $this->m_sName;} + + // recursive rendering + public function Render($aArgs = array()) + { + if (array_key_exists($this->m_sName, $aArgs)) + { + return $aArgs[$this->m_sName]; + } + elseif (is_null($aArgs)) + { + return ':'.$this->m_sName; + } + else + { + throw new CoreException('Missing query argument', array('expecting'=>$this->m_sName, 'available'=>$aArgs)); + } + } +} + // Temporary, until we implement functions and expression casting! // ... or until we implement a real full text search based in the MATCH() expression class ListExpression extends Expression @@ -293,12 +330,12 @@ class ListExpression extends Expression } // recursive rendering - public function Render() + public function Render($aArgs = array()) { $aRes = array(); foreach ($this->m_aExpressions as $oExpr) { - $aRes[] = $oExpr->Render(); + $aRes[] = $oExpr->Render($aArgs); } return '('.implode(', ', $aRes).')'; } @@ -353,12 +390,12 @@ class FunctionExpression extends Expression } // recursive rendering - public function Render() + public function Render($aArgs = array()) { $aRes = array(); foreach ($this->m_aArgs as $oExpr) { - $aRes[] = $oExpr->Render(); + $aRes[] = $oExpr->Render($aArgs); } return $this->m_sVerb.'('.implode(', ', $aRes).')'; } @@ -412,9 +449,9 @@ class IntervalExpression extends Expression } // recursive rendering - public function Render() + public function Render($aArgs = array()) { - return 'INTERVAL '.$this->m_oValue->Render().' '.$this->m_sUnit; + return 'INTERVAL '.$this->m_oValue->Render($aArgs).' '.$this->m_sUnit; } public function Translate($aTranslationData, $bMatchAll = true) @@ -449,12 +486,12 @@ class CharConcatExpression extends Expression } // recursive rendering - public function Render() + public function Render($aArgs = array()) { $aRes = array(); foreach ($this->m_aExpressions as $oExpr) { - $sCol = $oExpr->Render(); + $sCol = $oExpr->Render($aArgs); // Concat will be globally NULL if one single argument is null ! $aRes[] = "COALESCE($sCol, '')"; } diff --git a/trunk/core/metamodel.class.php b/trunk/core/metamodel.class.php index 275ad454a..bb7e92a05 100644 --- a/trunk/core/metamodel.class.php +++ b/trunk/core/metamodel.class.php @@ -394,6 +394,12 @@ abstract class MetaModel return (array_key_exists($sClass, self::$m_aAttribDefs)); } + public static function IsValidObject($oObject) + { + if (!is_object($oObject)) return false; + return (self::IsValidClass(get_class($oObject))); + } + public static function IsReconcKey($sClass, $sAttCode) { return (in_array($sAttCode, self::GetReconcKeys($sClass))); @@ -1161,7 +1167,7 @@ abstract class MetaModel return false; } - public static function MakeSelectQuery(DBObjectSearch $oFilter, $aOrderBy = array()) + public static function MakeSelectQuery(DBObjectSearch $oFilter, $aOrderBy = array(), $aArgs = array()) { $aTranslation = array(); $aClassAliases = array(); @@ -1188,8 +1194,30 @@ abstract class MetaModel } } + // Prepare arguments (translate any object into scalars) + // + $aScalarArgs = array(); + foreach($aArgs as $sArgName => $value) + { + if (self::IsValidObject($value)) + { + $aScalarArgs[$sArgName] = $value->GetKey(); + $aScalarArgs[$sArgName.'->id'] = $value->GetKey(); + + $sClass = get_class($value); + foreach(self::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) + { + $aScalarArgs[$sArgName.'->'.$sAttCode] = $value->Get($sAttCode); + } + } + else + { + $aScalarArgs[$sArgName] = (string) $value; + } + } + //MyHelpers::var_dump_html($oSelect->RenderSelect($aOrderBy)); - return $oSelect->RenderSelect($aOrderBy); + return $oSelect->RenderSelect($aOrderBy, $aScalarArgs); } public static function MakeDeleteQuery(DBObjectSearch $oFilter) diff --git a/trunk/core/oql/oql-lexer.php b/trunk/core/oql/oql-lexer.php index dede6ca1f..8853786ff 100644 --- a/trunk/core/oql/oql-lexer.php +++ b/trunk/core/oql/oql-lexer.php @@ -84,6 +84,7 @@ class OQLLexerRaw $rules = array( '/^[ \t\n]+/', '/^SELECT/', + '/^FROM/', '/^AS/', '/^WHERE/', '/^JOIN/', @@ -131,6 +132,7 @@ class OQLLexerRaw '/^[0-9]+|0x[0-9a-fA-F]+/', '/^\"([^\\\\\"]|\\\\\"|\\\\\\\\)*\"|'.chr(94).chr(39).'([^\\\\'.chr(39).']|\\\\'.chr(39).'|\\\\\\\\)*'.chr(39).'/', '/^([_a-zA-Z][_a-zA-Z0-9]*|`[^`]+`)/', + '/^:([_a-zA-Z][_a-zA-Z0-9]*->[_a-zA-Z][_a-zA-Z0-9]*|[_a-zA-Z][_a-zA-Z0-9]*)/', '/^\\./', ); $match = false; @@ -237,239 +239,249 @@ class OQLLexerRaw function yy_r1_2($yy_subpatterns) { - $this->token = OQLParser::AS_ALIAS; + $this->token = OQLParser::FROM; } function yy_r1_3($yy_subpatterns) { - $this->token = OQLParser::WHERE; + $this->token = OQLParser::AS_ALIAS; } function yy_r1_4($yy_subpatterns) { - $this->token = OQLParser::JOIN; + $this->token = OQLParser::WHERE; } function yy_r1_5($yy_subpatterns) { - $this->token = OQLParser::ON; + $this->token = OQLParser::JOIN; } function yy_r1_6($yy_subpatterns) { - $this->token = OQLParser::MATH_DIV; + $this->token = OQLParser::ON; } function yy_r1_7($yy_subpatterns) { - $this->token = OQLParser::MATH_MULT; + $this->token = OQLParser::MATH_DIV; } function yy_r1_8($yy_subpatterns) { - $this->token = OQLParser::MATH_PLUS; + $this->token = OQLParser::MATH_MULT; } function yy_r1_9($yy_subpatterns) { - $this->token = OQLParser::MATH_MINUS; + $this->token = OQLParser::MATH_PLUS; } function yy_r1_10($yy_subpatterns) { - $this->token = OQLParser::LOG_AND; + $this->token = OQLParser::MATH_MINUS; } function yy_r1_11($yy_subpatterns) { - $this->token = OQLParser::LOG_OR; + $this->token = OQLParser::LOG_AND; } function yy_r1_12($yy_subpatterns) { - $this->token = OQLParser::COMA; + $this->token = OQLParser::LOG_OR; } function yy_r1_13($yy_subpatterns) { - $this->token = OQLParser::PAR_OPEN; + $this->token = OQLParser::COMA; } function yy_r1_14($yy_subpatterns) { - $this->token = OQLParser::PAR_CLOSE; + $this->token = OQLParser::PAR_OPEN; } function yy_r1_15($yy_subpatterns) { - $this->token = OQLParser::EQ; + $this->token = OQLParser::PAR_CLOSE; } function yy_r1_16($yy_subpatterns) { - $this->token = OQLParser::NOT_EQ; + $this->token = OQLParser::EQ; } function yy_r1_17($yy_subpatterns) { - $this->token = OQLParser::GT; + $this->token = OQLParser::NOT_EQ; } function yy_r1_18($yy_subpatterns) { - $this->token = OQLParser::LT; + $this->token = OQLParser::GT; } function yy_r1_19($yy_subpatterns) { - $this->token = OQLParser::GE; + $this->token = OQLParser::LT; } function yy_r1_20($yy_subpatterns) { - $this->token = OQLParser::LE; + $this->token = OQLParser::GE; } function yy_r1_21($yy_subpatterns) { - $this->token = OQLParser::LIKE; + $this->token = OQLParser::LE; } function yy_r1_22($yy_subpatterns) { - $this->token = OQLParser::NOT_LIKE; + $this->token = OQLParser::LIKE; } function yy_r1_23($yy_subpatterns) { - $this->token = OQLParser::IN; + $this->token = OQLParser::NOT_LIKE; } function yy_r1_24($yy_subpatterns) { - $this->token = OQLParser::NOT_IN; + $this->token = OQLParser::IN; } function yy_r1_25($yy_subpatterns) { - $this->token = OQLParser::INTERVAL; + $this->token = OQLParser::NOT_IN; } function yy_r1_26($yy_subpatterns) { - $this->token = OQLParser::F_IF; + $this->token = OQLParser::INTERVAL; } function yy_r1_27($yy_subpatterns) { - $this->token = OQLParser::F_ELT; + $this->token = OQLParser::F_IF; } function yy_r1_28($yy_subpatterns) { - $this->token = OQLParser::F_COALESCE; + $this->token = OQLParser::F_ELT; } function yy_r1_29($yy_subpatterns) { - $this->token = OQLParser::F_CONCAT; + $this->token = OQLParser::F_COALESCE; } function yy_r1_30($yy_subpatterns) { - $this->token = OQLParser::F_SUBSTR; + $this->token = OQLParser::F_CONCAT; } function yy_r1_31($yy_subpatterns) { - $this->token = OQLParser::F_TRIM; + $this->token = OQLParser::F_SUBSTR; } function yy_r1_32($yy_subpatterns) { - $this->token = OQLParser::F_DATE; + $this->token = OQLParser::F_TRIM; } function yy_r1_33($yy_subpatterns) { - $this->token = OQLParser::F_DATE_FORMAT; + $this->token = OQLParser::F_DATE; } function yy_r1_34($yy_subpatterns) { - $this->token = OQLParser::F_CURRENT_DATE; + $this->token = OQLParser::F_DATE_FORMAT; } function yy_r1_35($yy_subpatterns) { - $this->token = OQLParser::F_NOW; + $this->token = OQLParser::F_CURRENT_DATE; } function yy_r1_36($yy_subpatterns) { - $this->token = OQLParser::F_TIME; + $this->token = OQLParser::F_NOW; } function yy_r1_37($yy_subpatterns) { - $this->token = OQLParser::F_TO_DAYS; + $this->token = OQLParser::F_TIME; } function yy_r1_38($yy_subpatterns) { - $this->token = OQLParser::F_FROM_DAYS; + $this->token = OQLParser::F_TO_DAYS; } function yy_r1_39($yy_subpatterns) { - $this->token = OQLParser::F_YEAR; + $this->token = OQLParser::F_FROM_DAYS; } function yy_r1_40($yy_subpatterns) { - $this->token = OQLParser::F_MONTH; + $this->token = OQLParser::F_YEAR; } function yy_r1_41($yy_subpatterns) { - $this->token = OQLParser::F_DAY; + $this->token = OQLParser::F_MONTH; } function yy_r1_42($yy_subpatterns) { - $this->token = OQLParser::F_DATE_ADD; + $this->token = OQLParser::F_DAY; } function yy_r1_43($yy_subpatterns) { - $this->token = OQLParser::F_DATE_SUB; + $this->token = OQLParser::F_DATE_ADD; } function yy_r1_44($yy_subpatterns) { - $this->token = OQLParser::F_ROUND; + $this->token = OQLParser::F_DATE_SUB; } function yy_r1_45($yy_subpatterns) { - $this->token = OQLParser::F_FLOOR; + $this->token = OQLParser::F_ROUND; } function yy_r1_46($yy_subpatterns) { - $this->token = OQLParser::NUMVAL; + $this->token = OQLParser::F_FLOOR; } function yy_r1_47($yy_subpatterns) { - $this->token = OQLParser::STRVAL; + $this->token = OQLParser::NUMVAL; } function yy_r1_48($yy_subpatterns) { - $this->token = OQLParser::NAME; + $this->token = OQLParser::STRVAL; } function yy_r1_49($yy_subpatterns) + { + + $this->token = OQLParser::NAME; + } + function yy_r1_50($yy_subpatterns) + { + + $this->token = OQLParser::VARNAME; + } + function yy_r1_51($yy_subpatterns) { $this->token = OQLParser::DOT; diff --git a/trunk/core/oql/oql-lexer.plex b/trunk/core/oql/oql-lexer.plex index 8196f540a..c8e90dda1 100644 --- a/trunk/core/oql/oql-lexer.plex +++ b/trunk/core/oql/oql-lexer.plex @@ -55,7 +55,8 @@ class OQLLexerRaw %line $this->line %matchlongest 1 whitespace = /[ \t\n]+/ -select = "SELECT" +select = "SELECT" +from = "FROM" as_alias = "AS" where = "WHERE" join = "JOIN" @@ -103,6 +104,7 @@ f_floor = "FLOOR" numval = /[0-9]+|0x[0-9a-fA-F]+/ strval = /"([^\\"]|\\"|\\\\)*"|'.chr(94).chr(39).'([^\\'.chr(39).']|\\'.chr(39).'|\\\\)*'.chr(39).'/ name = /([_a-zA-Z][_a-zA-Z0-9]*|`[^`]+`)/ +varname = /:([_a-zA-Z][_a-zA-Z0-9]*->[_a-zA-Z][_a-zA-Z0-9]*|[_a-zA-Z][_a-zA-Z0-9]*)/ dot = "." */ @@ -113,6 +115,9 @@ whitespace { select { $this->token = OQLParser::SELECT; } +from { + $this->token = OQLParser::FROM; +} as_alias { $this->token = OQLParser::AS_ALIAS; } @@ -254,6 +259,9 @@ strval { name { $this->token = OQLParser::NAME; } +varname { + $this->token = OQLParser::VARNAME; +} dot { $this->token = OQLParser::DOT; } diff --git a/trunk/core/oql/oql-parser.php b/trunk/core/oql/oql-parser.php index c3995650c..e66f48274 100644 --- a/trunk/core/oql/oql-parser.php +++ b/trunk/core/oql/oql-parser.php @@ -125,44 +125,45 @@ class OQLParserRaw#line 102 "oql-parser.php" const F_MONTH = 12; const F_YEAR = 13; const DOT = 14; - const NAME = 15; - const NUMVAL = 16; - const STRVAL = 17; - const NOT_EQ = 18; - const LOG_AND = 19; - const LOG_OR = 20; - const MATH_DIV = 21; - const MATH_MULT = 22; - const MATH_PLUS = 23; - const MATH_MINUS = 24; - const GT = 25; - const LT = 26; - const GE = 27; - const LE = 28; - const LIKE = 29; - const NOT_LIKE = 30; - const IN = 31; - const NOT_IN = 32; - const F_IF = 33; - const F_ELT = 34; - const F_COALESCE = 35; - const F_CONCAT = 36; - const F_SUBSTR = 37; - const F_TRIM = 38; - const F_DATE = 39; - const F_DATE_FORMAT = 40; - const F_CURRENT_DATE = 41; - const F_NOW = 42; - const F_TIME = 43; - const F_TO_DAYS = 44; - const F_FROM_DAYS = 45; - const F_DATE_ADD = 46; - const F_DATE_SUB = 47; - const F_ROUND = 48; - const F_FLOOR = 49; - const YY_NO_ACTION = 205; - const YY_ACCEPT_ACTION = 204; - const YY_ERROR_ACTION = 203; + const VARNAME = 15; + const NAME = 16; + const NUMVAL = 17; + const STRVAL = 18; + const NOT_EQ = 19; + const LOG_AND = 20; + const LOG_OR = 21; + const MATH_DIV = 22; + const MATH_MULT = 23; + const MATH_PLUS = 24; + const MATH_MINUS = 25; + const GT = 26; + const LT = 27; + const GE = 28; + const LE = 29; + const LIKE = 30; + const NOT_LIKE = 31; + const IN = 32; + const NOT_IN = 33; + const F_IF = 34; + const F_ELT = 35; + const F_COALESCE = 36; + const F_CONCAT = 37; + const F_SUBSTR = 38; + const F_TRIM = 39; + const F_DATE = 40; + const F_DATE_FORMAT = 41; + const F_CURRENT_DATE = 42; + const F_NOW = 43; + const F_TIME = 44; + const F_TO_DAYS = 45; + const F_FROM_DAYS = 46; + const F_DATE_ADD = 47; + const F_DATE_SUB = 48; + const F_ROUND = 49; + const F_FLOOR = 50; + const YY_NO_ACTION = 209; + const YY_ACCEPT_ACTION = 208; + const YY_ERROR_ACTION = 207; /* Next are that tables used to determine what action to take based on the ** current state and lookahead token. These tables are used to implement @@ -214,159 +215,161 @@ class OQLParserRaw#line 102 "oql-parser.php" ** shifting non-terminals after a reduce. ** self::$yy_default Default action for each state. */ - const YY_SZ_ACTTAB = 419; + const YY_SZ_ACTTAB = 429; static public $yy_action = array( - /* 0 */ 5, 57, 8, 4, 95, 96, 97, 6, 93, 76, - /* 10 */ 77, 89, 2, 53, 86, 50, 54, 25, 52, 55, - /* 20 */ 51, 46, 47, 49, 56, 70, 94, 110, 109, 108, - /* 30 */ 107, 111, 112, 115, 114, 113, 106, 71, 98, 99, - /* 40 */ 100, 104, 103, 26, 66, 38, 42, 9, 81, 5, - /* 50 */ 62, 44, 82, 95, 96, 97, 3, 93, 76, 77, - /* 60 */ 39, 102, 92, 75, 74, 73, 72, 75, 74, 73, - /* 70 */ 72, 10, 66, 41, 91, 94, 110, 109, 108, 107, - /* 80 */ 111, 112, 115, 114, 113, 106, 71, 98, 99, 100, - /* 90 */ 104, 103, 5, 63, 90, 22, 95, 96, 97, 61, - /* 100 */ 93, 76, 77, 65, 64, 60, 83, 11, 80, 79, - /* 110 */ 91, 33, 91, 22, 21, 18, 16, 12, 94, 110, - /* 120 */ 109, 108, 107, 111, 112, 115, 114, 113, 106, 71, - /* 130 */ 98, 99, 100, 104, 103, 204, 105, 87, 42, 23, - /* 140 */ 43, 24, 66, 88, 30, 28, 84, 45, 36, 6, - /* 150 */ 22, 20, 58, 15, 32, 37, 1, 76, 77, 101, - /* 160 */ 116, 75, 74, 73, 72, 41, 13, 66, 7, 160, - /* 170 */ 67, 93, 24, 42, 35, 78, 173, 173, 88, 34, - /* 180 */ 28, 84, 45, 40, 42, 173, 20, 173, 15, 69, - /* 190 */ 37, 173, 173, 173, 59, 173, 75, 74, 73, 72, - /* 200 */ 41, 42, 173, 173, 173, 173, 88, 34, 28, 84, - /* 210 */ 45, 41, 173, 173, 20, 173, 15, 173, 37, 173, - /* 220 */ 173, 173, 68, 173, 75, 74, 73, 72, 41, 173, - /* 230 */ 173, 173, 85, 42, 173, 173, 173, 173, 88, 30, - /* 240 */ 28, 84, 45, 173, 173, 173, 20, 173, 15, 173, - /* 250 */ 37, 173, 173, 173, 173, 173, 75, 74, 73, 72, - /* 260 */ 41, 42, 173, 173, 173, 173, 88, 17, 28, 84, - /* 270 */ 45, 173, 173, 173, 20, 173, 15, 42, 37, 173, - /* 280 */ 173, 48, 44, 173, 75, 74, 73, 72, 41, 173, - /* 290 */ 173, 173, 173, 42, 173, 173, 173, 173, 88, 27, - /* 300 */ 28, 84, 45, 173, 41, 173, 20, 173, 15, 173, - /* 310 */ 37, 173, 173, 173, 173, 173, 75, 74, 73, 72, - /* 320 */ 41, 42, 173, 173, 173, 173, 88, 173, 28, 84, - /* 330 */ 45, 173, 173, 173, 20, 173, 15, 173, 31, 173, - /* 340 */ 173, 173, 173, 173, 75, 74, 73, 72, 41, 173, - /* 350 */ 173, 173, 173, 42, 173, 173, 173, 173, 88, 173, - /* 360 */ 28, 84, 45, 173, 173, 173, 20, 173, 14, 173, - /* 370 */ 173, 173, 173, 173, 173, 173, 75, 74, 73, 72, - /* 380 */ 41, 42, 173, 173, 173, 173, 88, 173, 28, 84, - /* 390 */ 45, 42, 173, 173, 19, 173, 88, 173, 29, 84, - /* 400 */ 45, 173, 173, 173, 75, 74, 73, 72, 41, 173, - /* 410 */ 173, 173, 173, 173, 75, 74, 73, 72, 41, + /* 0 */ 4, 54, 8, 5, 96, 97, 98, 86, 95, 94, + /* 10 */ 76, 77, 80, 79, 53, 49, 51, 25, 45, 52, + /* 20 */ 55, 57, 46, 47, 50, 56, 70, 111, 110, 109, + /* 30 */ 108, 112, 113, 117, 116, 115, 114, 71, 106, 99, + /* 40 */ 100, 101, 105, 104, 26, 66, 66, 41, 67, 81, + /* 50 */ 4, 48, 43, 82, 96, 97, 98, 3, 95, 94, + /* 60 */ 76, 77, 38, 83, 11, 75, 74, 73, 72, 75, + /* 70 */ 74, 73, 72, 91, 63, 42, 22, 111, 110, 109, + /* 80 */ 108, 112, 113, 117, 116, 115, 114, 71, 106, 99, + /* 90 */ 100, 101, 105, 104, 4, 35, 6, 22, 96, 97, + /* 100 */ 98, 7, 95, 94, 76, 77, 65, 64, 60, 23, + /* 110 */ 6, 12, 13, 58, 41, 41, 91, 18, 61, 43, + /* 120 */ 69, 111, 110, 109, 108, 112, 113, 117, 116, 115, + /* 130 */ 114, 71, 106, 99, 100, 101, 105, 104, 208, 107, + /* 140 */ 87, 41, 42, 42, 39, 66, 88, 34, 27, 84, + /* 150 */ 89, 44, 93, 2, 36, 20, 22, 15, 92, 37, + /* 160 */ 76, 77, 102, 118, 9, 75, 74, 73, 72, 42, + /* 170 */ 94, 91, 66, 16, 24, 163, 21, 41, 103, 32, + /* 180 */ 1, 62, 88, 33, 27, 84, 89, 44, 40, 21, + /* 190 */ 31, 20, 78, 15, 90, 37, 10, 177, 177, 59, + /* 200 */ 177, 75, 74, 73, 72, 42, 41, 177, 177, 177, + /* 210 */ 177, 88, 33, 27, 84, 89, 44, 177, 177, 177, + /* 220 */ 20, 177, 15, 177, 37, 177, 177, 177, 68, 177, + /* 230 */ 75, 74, 73, 72, 42, 177, 177, 85, 41, 177, + /* 240 */ 177, 177, 177, 88, 34, 27, 84, 89, 44, 177, + /* 250 */ 177, 177, 20, 177, 15, 177, 37, 177, 177, 177, + /* 260 */ 177, 177, 75, 74, 73, 72, 42, 41, 177, 177, + /* 270 */ 177, 177, 88, 17, 27, 84, 89, 44, 177, 177, + /* 280 */ 177, 20, 177, 15, 177, 37, 177, 177, 177, 177, + /* 290 */ 177, 75, 74, 73, 72, 42, 177, 177, 177, 41, + /* 300 */ 177, 177, 177, 177, 88, 29, 27, 84, 89, 44, + /* 310 */ 177, 177, 177, 20, 177, 15, 177, 37, 177, 177, + /* 320 */ 177, 177, 177, 75, 74, 73, 72, 42, 41, 177, + /* 330 */ 177, 177, 177, 88, 177, 27, 84, 89, 44, 177, + /* 340 */ 177, 177, 20, 177, 15, 177, 30, 177, 177, 177, + /* 350 */ 177, 177, 75, 74, 73, 72, 42, 177, 177, 177, + /* 360 */ 41, 177, 177, 177, 177, 88, 177, 27, 84, 89, + /* 370 */ 44, 177, 177, 177, 20, 177, 14, 177, 177, 177, + /* 380 */ 177, 177, 177, 177, 75, 74, 73, 72, 42, 41, + /* 390 */ 177, 177, 177, 177, 88, 177, 27, 84, 89, 44, + /* 400 */ 41, 177, 177, 19, 177, 88, 177, 28, 84, 89, + /* 410 */ 44, 177, 177, 75, 74, 73, 72, 42, 177, 177, + /* 420 */ 177, 177, 177, 177, 75, 74, 73, 72, 42, ); static public $yy_lookahead = array( - /* 0 */ 7, 6, 70, 10, 11, 12, 13, 73, 15, 16, - /* 10 */ 17, 8, 9, 18, 56, 83, 84, 54, 23, 24, - /* 20 */ 25, 26, 27, 28, 29, 30, 33, 34, 35, 36, + /* 0 */ 7, 6, 72, 10, 11, 12, 13, 57, 15, 16, + /* 10 */ 17, 18, 32, 33, 19, 85, 86, 55, 55, 24, + /* 20 */ 25, 26, 27, 28, 29, 30, 31, 34, 35, 36, /* 30 */ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - /* 40 */ 47, 48, 49, 1, 81, 54, 54, 68, 62, 7, - /* 50 */ 58, 59, 62, 11, 12, 13, 3, 15, 16, 17, - /* 60 */ 74, 82, 8, 77, 78, 79, 80, 77, 78, 79, - /* 70 */ 80, 7, 81, 81, 20, 33, 34, 35, 36, 37, - /* 80 */ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - /* 90 */ 48, 49, 7, 55, 66, 57, 11, 12, 13, 56, - /* 100 */ 15, 16, 17, 11, 12, 13, 8, 9, 31, 32, - /* 110 */ 20, 55, 20, 57, 2, 54, 6, 5, 33, 34, - /* 120 */ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - /* 130 */ 45, 46, 47, 48, 49, 51, 52, 53, 54, 2, - /* 140 */ 54, 4, 81, 59, 60, 61, 62, 63, 55, 73, - /* 150 */ 57, 67, 76, 69, 14, 71, 7, 16, 17, 21, - /* 160 */ 22, 77, 78, 79, 80, 81, 5, 81, 72, 14, - /* 170 */ 19, 15, 4, 54, 65, 81, 85, 85, 59, 60, - /* 180 */ 61, 62, 63, 64, 54, 85, 67, 85, 69, 59, - /* 190 */ 71, 85, 85, 85, 75, 85, 77, 78, 79, 80, - /* 200 */ 81, 54, 85, 85, 85, 85, 59, 60, 61, 62, - /* 210 */ 63, 81, 85, 85, 67, 85, 69, 85, 71, 85, - /* 220 */ 85, 85, 75, 85, 77, 78, 79, 80, 81, 85, - /* 230 */ 85, 85, 53, 54, 85, 85, 85, 85, 59, 60, - /* 240 */ 61, 62, 63, 85, 85, 85, 67, 85, 69, 85, - /* 250 */ 71, 85, 85, 85, 85, 85, 77, 78, 79, 80, - /* 260 */ 81, 54, 85, 85, 85, 85, 59, 60, 61, 62, - /* 270 */ 63, 85, 85, 85, 67, 85, 69, 54, 71, 85, - /* 280 */ 85, 58, 59, 85, 77, 78, 79, 80, 81, 85, - /* 290 */ 85, 85, 85, 54, 85, 85, 85, 85, 59, 60, - /* 300 */ 61, 62, 63, 85, 81, 85, 67, 85, 69, 85, - /* 310 */ 71, 85, 85, 85, 85, 85, 77, 78, 79, 80, - /* 320 */ 81, 54, 85, 85, 85, 85, 59, 85, 61, 62, - /* 330 */ 63, 85, 85, 85, 67, 85, 69, 85, 71, 85, - /* 340 */ 85, 85, 85, 85, 77, 78, 79, 80, 81, 85, - /* 350 */ 85, 85, 85, 54, 85, 85, 85, 85, 59, 85, - /* 360 */ 61, 62, 63, 85, 85, 85, 67, 85, 69, 85, - /* 370 */ 85, 85, 85, 85, 85, 85, 77, 78, 79, 80, - /* 380 */ 81, 54, 85, 85, 85, 85, 59, 85, 61, 62, - /* 390 */ 63, 54, 85, 85, 67, 85, 59, 85, 61, 62, - /* 400 */ 63, 85, 85, 85, 77, 78, 79, 80, 81, 85, - /* 410 */ 85, 85, 85, 85, 77, 78, 79, 80, 81, + /* 40 */ 47, 48, 49, 50, 1, 83, 83, 55, 20, 63, + /* 50 */ 7, 59, 60, 63, 11, 12, 13, 3, 15, 16, + /* 60 */ 17, 18, 76, 8, 9, 79, 80, 81, 82, 79, + /* 70 */ 80, 81, 82, 21, 56, 83, 58, 34, 35, 36, + /* 80 */ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + /* 90 */ 47, 48, 49, 50, 7, 56, 75, 58, 11, 12, + /* 100 */ 13, 74, 15, 16, 17, 18, 11, 12, 13, 2, + /* 110 */ 75, 5, 5, 78, 55, 55, 21, 55, 59, 60, + /* 120 */ 60, 34, 35, 36, 37, 38, 39, 40, 41, 42, + /* 130 */ 43, 44, 45, 46, 47, 48, 49, 50, 52, 53, + /* 140 */ 54, 55, 83, 83, 55, 83, 60, 61, 62, 63, + /* 150 */ 64, 65, 8, 9, 56, 69, 58, 71, 8, 73, + /* 160 */ 17, 18, 22, 23, 70, 79, 80, 81, 82, 83, + /* 170 */ 16, 21, 83, 6, 2, 14, 4, 55, 84, 14, + /* 180 */ 7, 57, 60, 61, 62, 63, 64, 65, 66, 4, + /* 190 */ 67, 69, 83, 71, 68, 73, 7, 87, 87, 77, + /* 200 */ 87, 79, 80, 81, 82, 83, 55, 87, 87, 87, + /* 210 */ 87, 60, 61, 62, 63, 64, 65, 87, 87, 87, + /* 220 */ 69, 87, 71, 87, 73, 87, 87, 87, 77, 87, + /* 230 */ 79, 80, 81, 82, 83, 87, 87, 54, 55, 87, + /* 240 */ 87, 87, 87, 60, 61, 62, 63, 64, 65, 87, + /* 250 */ 87, 87, 69, 87, 71, 87, 73, 87, 87, 87, + /* 260 */ 87, 87, 79, 80, 81, 82, 83, 55, 87, 87, + /* 270 */ 87, 87, 60, 61, 62, 63, 64, 65, 87, 87, + /* 280 */ 87, 69, 87, 71, 87, 73, 87, 87, 87, 87, + /* 290 */ 87, 79, 80, 81, 82, 83, 87, 87, 87, 55, + /* 300 */ 87, 87, 87, 87, 60, 61, 62, 63, 64, 65, + /* 310 */ 87, 87, 87, 69, 87, 71, 87, 73, 87, 87, + /* 320 */ 87, 87, 87, 79, 80, 81, 82, 83, 55, 87, + /* 330 */ 87, 87, 87, 60, 87, 62, 63, 64, 65, 87, + /* 340 */ 87, 87, 69, 87, 71, 87, 73, 87, 87, 87, + /* 350 */ 87, 87, 79, 80, 81, 82, 83, 87, 87, 87, + /* 360 */ 55, 87, 87, 87, 87, 60, 87, 62, 63, 64, + /* 370 */ 65, 87, 87, 87, 69, 87, 71, 87, 87, 87, + /* 380 */ 87, 87, 87, 87, 79, 80, 81, 82, 83, 55, + /* 390 */ 87, 87, 87, 87, 60, 87, 62, 63, 64, 65, + /* 400 */ 55, 87, 87, 69, 87, 60, 87, 62, 63, 64, + /* 410 */ 65, 87, 87, 79, 80, 81, 82, 83, 87, 87, + /* 420 */ 87, 87, 87, 87, 79, 80, 81, 82, 83, ); - const YY_SHIFT_USE_DFLT = -8; + const YY_SHIFT_USE_DFLT = -21; const YY_SHIFT_MAX = 45; static public $yy_shift_ofst = array( - /* 0 */ 42, -7, -7, 85, 85, 85, 85, 85, 85, 85, - /* 10 */ 141, 141, 156, 156, -5, -5, 156, 92, 137, 138, - /* 20 */ 138, 156, 168, 156, 156, 168, 156, 54, 77, 77, - /* 30 */ 90, 151, 156, 53, 90, 64, 53, 151, 112, 98, - /* 40 */ 3, 155, 140, 161, 110, 149, + /* 0 */ 43, -7, -7, 87, 87, 87, 87, 87, 87, 87, + /* 10 */ 143, 143, 154, 154, -5, -5, 154, 95, 172, 140, + /* 20 */ 140, 154, 185, 154, 154, 185, 154, -20, -20, 150, + /* 30 */ 28, 189, 154, 52, 52, 54, 54, 28, 55, 107, + /* 40 */ 144, 165, 161, 167, 173, 106, ); - const YY_REDUCE_USE_DFLT = -69; + const YY_REDUCE_USE_DFLT = -71; const YY_REDUCE_MAX = 37; static public $yy_reduce_ofst = array( - /* 0 */ 84, 119, 147, 179, 207, 239, 267, 299, 327, 337, - /* 10 */ -14, -10, 223, -8, -68, -68, 130, 76, 93, -21, - /* 20 */ -21, 86, 38, -37, -9, 56, 61, -66, 109, 109, - /* 30 */ -66, 96, 94, 43, -66, 28, -42, 96, + /* 0 */ 86, 122, 151, 183, 244, 212, 273, 305, 334, 345, + /* 10 */ -14, -10, 59, -8, -70, -70, 60, 35, 98, 94, + /* 20 */ 94, 89, 18, -37, -38, 39, 62, 123, 123, 21, + /* 30 */ 27, 126, 109, 21, 21, 124, -50, 27, ); static public $yyExpectedTokens = array( - /* 0 */ array(1, 7, 11, 12, 13, 15, 16, 17, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, ), - /* 1 */ array(7, 10, 11, 12, 13, 15, 16, 17, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, ), - /* 2 */ array(7, 10, 11, 12, 13, 15, 16, 17, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, ), - /* 3 */ array(7, 11, 12, 13, 15, 16, 17, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, ), - /* 4 */ array(7, 11, 12, 13, 15, 16, 17, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, ), - /* 5 */ array(7, 11, 12, 13, 15, 16, 17, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, ), - /* 6 */ array(7, 11, 12, 13, 15, 16, 17, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, ), - /* 7 */ array(7, 11, 12, 13, 15, 16, 17, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, ), - /* 8 */ array(7, 11, 12, 13, 15, 16, 17, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, ), - /* 9 */ array(7, 11, 12, 13, 15, 16, 17, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, ), - /* 10 */ array(16, 17, ), - /* 11 */ array(16, 17, ), - /* 12 */ array(15, ), - /* 13 */ array(15, ), - /* 14 */ array(6, 18, 23, 24, 25, 26, 27, 28, 29, 30, ), - /* 15 */ array(6, 18, 23, 24, 25, 26, 27, 28, 29, 30, ), - /* 16 */ array(15, ), - /* 17 */ array(11, 12, 13, 20, ), + /* 0 */ array(1, 7, 11, 12, 13, 15, 16, 17, 18, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, ), + /* 1 */ array(7, 10, 11, 12, 13, 15, 16, 17, 18, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, ), + /* 2 */ array(7, 10, 11, 12, 13, 15, 16, 17, 18, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, ), + /* 3 */ array(7, 11, 12, 13, 15, 16, 17, 18, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, ), + /* 4 */ array(7, 11, 12, 13, 15, 16, 17, 18, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, ), + /* 5 */ array(7, 11, 12, 13, 15, 16, 17, 18, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, ), + /* 6 */ array(7, 11, 12, 13, 15, 16, 17, 18, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, ), + /* 7 */ array(7, 11, 12, 13, 15, 16, 17, 18, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, ), + /* 8 */ array(7, 11, 12, 13, 15, 16, 17, 18, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, ), + /* 9 */ array(7, 11, 12, 13, 15, 16, 17, 18, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, ), + /* 10 */ array(17, 18, ), + /* 11 */ array(17, 18, ), + /* 12 */ array(16, ), + /* 13 */ array(16, ), + /* 14 */ array(6, 19, 24, 25, 26, 27, 28, 29, 30, 31, ), + /* 15 */ array(6, 19, 24, 25, 26, 27, 28, 29, 30, 31, ), + /* 16 */ array(16, ), + /* 17 */ array(11, 12, 13, 21, ), /* 18 */ array(2, 4, ), - /* 19 */ array(21, 22, ), - /* 20 */ array(21, 22, ), - /* 21 */ array(15, ), + /* 19 */ array(22, 23, ), + /* 20 */ array(22, 23, ), + /* 21 */ array(16, ), /* 22 */ array(4, ), - /* 23 */ array(15, ), - /* 24 */ array(15, ), + /* 23 */ array(16, ), + /* 24 */ array(16, ), /* 25 */ array(4, ), - /* 26 */ array(15, ), - /* 27 */ array(8, 20, ), - /* 28 */ array(31, 32, ), - /* 29 */ array(31, 32, ), + /* 26 */ array(16, ), + /* 27 */ array(32, 33, ), + /* 28 */ array(32, 33, ), + /* 29 */ array(8, 21, ), /* 30 */ array(20, ), - /* 31 */ array(19, ), - /* 32 */ array(15, ), - /* 33 */ array(3, ), - /* 34 */ array(20, ), - /* 35 */ array(7, ), + /* 31 */ array(7, ), + /* 32 */ array(16, ), + /* 33 */ array(21, ), + /* 34 */ array(21, ), + /* 35 */ array(3, ), /* 36 */ array(3, ), - /* 37 */ array(19, ), - /* 38 */ array(2, 5, ), - /* 39 */ array(8, 9, ), + /* 37 */ array(20, ), + /* 38 */ array(8, 9, ), + /* 39 */ array(2, 5, ), /* 40 */ array(8, 9, ), /* 41 */ array(14, ), /* 42 */ array(14, ), - /* 43 */ array(5, ), - /* 44 */ array(6, ), - /* 45 */ array(7, ), + /* 43 */ array(6, ), + /* 44 */ array(7, ), + /* 45 */ array(5, ), /* 46 */ array(), /* 47 */ array(), /* 48 */ array(), @@ -438,20 +441,22 @@ static public $yy_action = array( /* 114 */ array(), /* 115 */ array(), /* 116 */ array(), + /* 117 */ array(), + /* 118 */ array(), ); static public $yy_default = array( - /* 0 */ 203, 146, 203, 203, 203, 203, 203, 203, 203, 203, - /* 10 */ 203, 203, 203, 203, 140, 139, 203, 203, 125, 138, - /* 20 */ 137, 203, 124, 203, 203, 125, 203, 203, 135, 136, - /* 30 */ 129, 142, 203, 122, 149, 203, 122, 141, 203, 203, - /* 40 */ 203, 158, 203, 203, 203, 203, 176, 177, 127, 178, - /* 50 */ 165, 175, 173, 168, 166, 174, 179, 167, 150, 147, - /* 60 */ 153, 120, 126, 123, 152, 151, 160, 169, 148, 128, - /* 70 */ 180, 194, 157, 156, 155, 154, 162, 163, 159, 182, - /* 80 */ 181, 144, 145, 143, 130, 121, 119, 118, 131, 132, - /* 90 */ 134, 170, 133, 161, 183, 198, 197, 196, 195, 199, - /* 100 */ 200, 171, 164, 202, 201, 117, 193, 187, 186, 185, - /* 110 */ 184, 188, 189, 192, 191, 190, 172, + /* 0 */ 207, 149, 207, 207, 207, 207, 207, 207, 207, 207, + /* 10 */ 207, 207, 207, 207, 143, 142, 207, 207, 127, 141, + /* 20 */ 140, 207, 126, 207, 207, 127, 207, 138, 139, 207, + /* 30 */ 145, 207, 207, 152, 131, 124, 124, 144, 207, 207, + /* 40 */ 207, 207, 161, 207, 207, 207, 180, 181, 129, 169, + /* 50 */ 182, 170, 177, 172, 171, 178, 183, 179, 153, 150, + /* 60 */ 156, 128, 122, 125, 155, 154, 163, 173, 151, 130, + /* 70 */ 184, 197, 160, 159, 158, 157, 166, 167, 162, 186, + /* 80 */ 185, 147, 148, 146, 132, 123, 121, 120, 133, 134, + /* 90 */ 137, 174, 136, 135, 165, 164, 202, 201, 200, 199, + /* 100 */ 203, 204, 175, 168, 206, 205, 198, 119, 190, 189, + /* 110 */ 188, 187, 191, 192, 196, 195, 194, 193, 176, ); /* The next thing included is series of defines which control ** various aspects of the generated parser. @@ -468,11 +473,11 @@ static public $yy_action = array( ** self::YYERRORSYMBOL is the code number of the error symbol. If not ** defined, then do no error processing. */ - const YYNOCODE = 86; + const YYNOCODE = 88; const YYSTACKDEPTH = 100; - const YYNSTATE = 117; - const YYNRULE = 86; - const YYERRORSYMBOL = 50; + const YYNSTATE = 119; + const YYNRULE = 88; + const YYERRORSYMBOL = 51; const YYERRSYMDT = 'yy0'; const YYFALLBACK = 0; /** The next table maps tokens into fallback tokens. If a construct @@ -557,25 +562,25 @@ static public $yy_action = array( '$', 'SELECT', 'AS_ALIAS', 'WHERE', 'JOIN', 'ON', 'EQ', 'PAR_OPEN', 'PAR_CLOSE', 'COMA', 'INTERVAL', 'F_DAY', - 'F_MONTH', 'F_YEAR', 'DOT', 'NAME', - 'NUMVAL', 'STRVAL', 'NOT_EQ', 'LOG_AND', - 'LOG_OR', 'MATH_DIV', 'MATH_MULT', 'MATH_PLUS', - 'MATH_MINUS', 'GT', 'LT', 'GE', - 'LE', 'LIKE', 'NOT_LIKE', 'IN', - 'NOT_IN', 'F_IF', 'F_ELT', 'F_COALESCE', - 'F_CONCAT', 'F_SUBSTR', 'F_TRIM', 'F_DATE', - 'F_DATE_FORMAT', 'F_CURRENT_DATE', 'F_NOW', 'F_TIME', - 'F_TO_DAYS', 'F_FROM_DAYS', 'F_DATE_ADD', 'F_DATE_SUB', - 'F_ROUND', 'F_FLOOR', 'error', 'result', - 'query', 'condition', 'class_name', 'join_statement', - 'where_statement', 'join_item', 'join_condition', 'field_id', - 'expression_prio4', 'expression_basic', 'scalar', 'func_name', - 'arg_list', 'list_operator', 'list', 'expression_prio1', - 'operator1', 'expression_prio2', 'operator2', 'expression_prio3', - 'operator3', 'operator4', 'scalar_list', 'argument', - 'interval_unit', 'num_scalar', 'str_scalar', 'num_value', - 'str_value', 'name', 'num_operator1', 'num_operator2', - 'str_operator', + 'F_MONTH', 'F_YEAR', 'DOT', 'VARNAME', + 'NAME', 'NUMVAL', 'STRVAL', 'NOT_EQ', + 'LOG_AND', 'LOG_OR', 'MATH_DIV', 'MATH_MULT', + 'MATH_PLUS', 'MATH_MINUS', 'GT', 'LT', + 'GE', 'LE', 'LIKE', 'NOT_LIKE', + 'IN', 'NOT_IN', 'F_IF', 'F_ELT', + 'F_COALESCE', 'F_CONCAT', 'F_SUBSTR', 'F_TRIM', + 'F_DATE', 'F_DATE_FORMAT', 'F_CURRENT_DATE', 'F_NOW', + 'F_TIME', 'F_TO_DAYS', 'F_FROM_DAYS', 'F_DATE_ADD', + 'F_DATE_SUB', 'F_ROUND', 'F_FLOOR', 'error', + 'result', 'query', 'condition', 'class_name', + 'join_statement', 'where_statement', 'join_item', 'join_condition', + 'field_id', 'expression_prio4', 'expression_basic', 'scalar', + 'var_name', 'func_name', 'arg_list', 'list_operator', + 'list', 'expression_prio1', 'operator1', 'expression_prio2', + 'operator2', 'expression_prio3', 'operator3', 'operator4', + 'scalar_list', 'argument', 'interval_unit', 'num_scalar', + 'str_scalar', 'num_value', 'str_value', 'name', + 'num_operator1', 'num_operator2', 'str_operator', ); /** @@ -598,77 +603,79 @@ static public $yy_action = array( /* 12 */ "condition ::= expression_prio4", /* 13 */ "expression_basic ::= scalar", /* 14 */ "expression_basic ::= field_id", - /* 15 */ "expression_basic ::= func_name PAR_OPEN arg_list PAR_CLOSE", - /* 16 */ "expression_basic ::= PAR_OPEN expression_prio4 PAR_CLOSE", - /* 17 */ "expression_basic ::= expression_basic list_operator list", - /* 18 */ "expression_prio1 ::= expression_basic", - /* 19 */ "expression_prio1 ::= expression_prio1 operator1 expression_basic", - /* 20 */ "expression_prio2 ::= expression_prio1", - /* 21 */ "expression_prio2 ::= expression_prio2 operator2 expression_prio1", - /* 22 */ "expression_prio3 ::= expression_prio2", - /* 23 */ "expression_prio3 ::= expression_prio3 operator3 expression_prio2", - /* 24 */ "expression_prio4 ::= expression_prio3", - /* 25 */ "expression_prio4 ::= expression_prio4 operator4 expression_prio3", - /* 26 */ "list ::= PAR_OPEN scalar_list PAR_CLOSE", - /* 27 */ "scalar_list ::= scalar", - /* 28 */ "scalar_list ::= scalar_list COMA scalar", - /* 29 */ "arg_list ::=", - /* 30 */ "arg_list ::= argument", - /* 31 */ "arg_list ::= arg_list COMA argument", - /* 32 */ "argument ::= expression_prio4", - /* 33 */ "argument ::= INTERVAL expression_prio4 interval_unit", - /* 34 */ "interval_unit ::= F_DAY", - /* 35 */ "interval_unit ::= F_MONTH", - /* 36 */ "interval_unit ::= F_YEAR", - /* 37 */ "scalar ::= num_scalar", - /* 38 */ "scalar ::= str_scalar", - /* 39 */ "num_scalar ::= num_value", - /* 40 */ "str_scalar ::= str_value", - /* 41 */ "field_id ::= name", - /* 42 */ "field_id ::= class_name DOT name", - /* 43 */ "class_name ::= name", - /* 44 */ "name ::= NAME", - /* 45 */ "num_value ::= NUMVAL", - /* 46 */ "str_value ::= STRVAL", - /* 47 */ "operator1 ::= num_operator1", - /* 48 */ "operator2 ::= num_operator2", - /* 49 */ "operator2 ::= str_operator", - /* 50 */ "operator2 ::= EQ", - /* 51 */ "operator2 ::= NOT_EQ", - /* 52 */ "operator3 ::= LOG_AND", - /* 53 */ "operator4 ::= LOG_OR", - /* 54 */ "num_operator1 ::= MATH_DIV", - /* 55 */ "num_operator1 ::= MATH_MULT", - /* 56 */ "num_operator2 ::= MATH_PLUS", - /* 57 */ "num_operator2 ::= MATH_MINUS", - /* 58 */ "num_operator2 ::= GT", - /* 59 */ "num_operator2 ::= LT", - /* 60 */ "num_operator2 ::= GE", - /* 61 */ "num_operator2 ::= LE", - /* 62 */ "str_operator ::= LIKE", - /* 63 */ "str_operator ::= NOT_LIKE", - /* 64 */ "list_operator ::= IN", - /* 65 */ "list_operator ::= NOT_IN", - /* 66 */ "func_name ::= F_IF", - /* 67 */ "func_name ::= F_ELT", - /* 68 */ "func_name ::= F_COALESCE", - /* 69 */ "func_name ::= F_CONCAT", - /* 70 */ "func_name ::= F_SUBSTR", - /* 71 */ "func_name ::= F_TRIM", - /* 72 */ "func_name ::= F_DATE", - /* 73 */ "func_name ::= F_DATE_FORMAT", - /* 74 */ "func_name ::= F_CURRENT_DATE", - /* 75 */ "func_name ::= F_NOW", - /* 76 */ "func_name ::= F_TIME", - /* 77 */ "func_name ::= F_TO_DAYS", - /* 78 */ "func_name ::= F_FROM_DAYS", - /* 79 */ "func_name ::= F_YEAR", - /* 80 */ "func_name ::= F_MONTH", - /* 81 */ "func_name ::= F_DAY", - /* 82 */ "func_name ::= F_DATE_ADD", - /* 83 */ "func_name ::= F_DATE_SUB", - /* 84 */ "func_name ::= F_ROUND", - /* 85 */ "func_name ::= F_FLOOR", + /* 15 */ "expression_basic ::= var_name", + /* 16 */ "expression_basic ::= func_name PAR_OPEN arg_list PAR_CLOSE", + /* 17 */ "expression_basic ::= PAR_OPEN expression_prio4 PAR_CLOSE", + /* 18 */ "expression_basic ::= expression_basic list_operator list", + /* 19 */ "expression_prio1 ::= expression_basic", + /* 20 */ "expression_prio1 ::= expression_prio1 operator1 expression_basic", + /* 21 */ "expression_prio2 ::= expression_prio1", + /* 22 */ "expression_prio2 ::= expression_prio2 operator2 expression_prio1", + /* 23 */ "expression_prio3 ::= expression_prio2", + /* 24 */ "expression_prio3 ::= expression_prio3 operator3 expression_prio2", + /* 25 */ "expression_prio4 ::= expression_prio3", + /* 26 */ "expression_prio4 ::= expression_prio4 operator4 expression_prio3", + /* 27 */ "list ::= PAR_OPEN scalar_list PAR_CLOSE", + /* 28 */ "scalar_list ::= scalar", + /* 29 */ "scalar_list ::= scalar_list COMA scalar", + /* 30 */ "arg_list ::=", + /* 31 */ "arg_list ::= argument", + /* 32 */ "arg_list ::= arg_list COMA argument", + /* 33 */ "argument ::= expression_prio4", + /* 34 */ "argument ::= INTERVAL expression_prio4 interval_unit", + /* 35 */ "interval_unit ::= F_DAY", + /* 36 */ "interval_unit ::= F_MONTH", + /* 37 */ "interval_unit ::= F_YEAR", + /* 38 */ "scalar ::= num_scalar", + /* 39 */ "scalar ::= str_scalar", + /* 40 */ "num_scalar ::= num_value", + /* 41 */ "str_scalar ::= str_value", + /* 42 */ "field_id ::= name", + /* 43 */ "field_id ::= class_name DOT name", + /* 44 */ "class_name ::= name", + /* 45 */ "var_name ::= VARNAME", + /* 46 */ "name ::= NAME", + /* 47 */ "num_value ::= NUMVAL", + /* 48 */ "str_value ::= STRVAL", + /* 49 */ "operator1 ::= num_operator1", + /* 50 */ "operator2 ::= num_operator2", + /* 51 */ "operator2 ::= str_operator", + /* 52 */ "operator2 ::= EQ", + /* 53 */ "operator2 ::= NOT_EQ", + /* 54 */ "operator3 ::= LOG_AND", + /* 55 */ "operator4 ::= LOG_OR", + /* 56 */ "num_operator1 ::= MATH_DIV", + /* 57 */ "num_operator1 ::= MATH_MULT", + /* 58 */ "num_operator2 ::= MATH_PLUS", + /* 59 */ "num_operator2 ::= MATH_MINUS", + /* 60 */ "num_operator2 ::= GT", + /* 61 */ "num_operator2 ::= LT", + /* 62 */ "num_operator2 ::= GE", + /* 63 */ "num_operator2 ::= LE", + /* 64 */ "str_operator ::= LIKE", + /* 65 */ "str_operator ::= NOT_LIKE", + /* 66 */ "list_operator ::= IN", + /* 67 */ "list_operator ::= NOT_IN", + /* 68 */ "func_name ::= F_IF", + /* 69 */ "func_name ::= F_ELT", + /* 70 */ "func_name ::= F_COALESCE", + /* 71 */ "func_name ::= F_CONCAT", + /* 72 */ "func_name ::= F_SUBSTR", + /* 73 */ "func_name ::= F_TRIM", + /* 74 */ "func_name ::= F_DATE", + /* 75 */ "func_name ::= F_DATE_FORMAT", + /* 76 */ "func_name ::= F_CURRENT_DATE", + /* 77 */ "func_name ::= F_NOW", + /* 78 */ "func_name ::= F_TIME", + /* 79 */ "func_name ::= F_TO_DAYS", + /* 80 */ "func_name ::= F_FROM_DAYS", + /* 81 */ "func_name ::= F_YEAR", + /* 82 */ "func_name ::= F_MONTH", + /* 83 */ "func_name ::= F_DAY", + /* 84 */ "func_name ::= F_DATE_ADD", + /* 85 */ "func_name ::= F_DATE_SUB", + /* 86 */ "func_name ::= F_ROUND", + /* 87 */ "func_name ::= F_FLOOR", ); /** @@ -1033,92 +1040,94 @@ static public $yy_action = array( * */ static public $yyRuleInfo = array( - array( 'lhs' => 51, 'rhs' => 1 ), - array( 'lhs' => 51, 'rhs' => 1 ), - array( 'lhs' => 52, 'rhs' => 4 ), - array( 'lhs' => 52, 'rhs' => 6 ), + array( 'lhs' => 52, 'rhs' => 1 ), + array( 'lhs' => 52, 'rhs' => 1 ), + array( 'lhs' => 53, 'rhs' => 4 ), + array( 'lhs' => 53, 'rhs' => 6 ), + array( 'lhs' => 57, 'rhs' => 2 ), + array( 'lhs' => 57, 'rhs' => 0 ), array( 'lhs' => 56, 'rhs' => 2 ), + array( 'lhs' => 56, 'rhs' => 1 ), array( 'lhs' => 56, 'rhs' => 0 ), - array( 'lhs' => 55, 'rhs' => 2 ), - array( 'lhs' => 55, 'rhs' => 1 ), - array( 'lhs' => 55, 'rhs' => 0 ), - array( 'lhs' => 57, 'rhs' => 6 ), - array( 'lhs' => 57, 'rhs' => 4 ), - array( 'lhs' => 58, 'rhs' => 3 ), - array( 'lhs' => 53, 'rhs' => 1 ), - array( 'lhs' => 61, 'rhs' => 1 ), - array( 'lhs' => 61, 'rhs' => 1 ), - array( 'lhs' => 61, 'rhs' => 4 ), - array( 'lhs' => 61, 'rhs' => 3 ), - array( 'lhs' => 61, 'rhs' => 3 ), - array( 'lhs' => 67, 'rhs' => 1 ), - array( 'lhs' => 67, 'rhs' => 3 ), + array( 'lhs' => 58, 'rhs' => 6 ), + array( 'lhs' => 58, 'rhs' => 4 ), + array( 'lhs' => 59, 'rhs' => 3 ), + array( 'lhs' => 54, 'rhs' => 1 ), + array( 'lhs' => 62, 'rhs' => 1 ), + array( 'lhs' => 62, 'rhs' => 1 ), + array( 'lhs' => 62, 'rhs' => 1 ), + array( 'lhs' => 62, 'rhs' => 4 ), + array( 'lhs' => 62, 'rhs' => 3 ), + array( 'lhs' => 62, 'rhs' => 3 ), array( 'lhs' => 69, 'rhs' => 1 ), array( 'lhs' => 69, 'rhs' => 3 ), array( 'lhs' => 71, 'rhs' => 1 ), array( 'lhs' => 71, 'rhs' => 3 ), - array( 'lhs' => 60, 'rhs' => 1 ), - array( 'lhs' => 60, 'rhs' => 3 ), + array( 'lhs' => 73, 'rhs' => 1 ), + array( 'lhs' => 73, 'rhs' => 3 ), + array( 'lhs' => 61, 'rhs' => 1 ), + array( 'lhs' => 61, 'rhs' => 3 ), + array( 'lhs' => 68, 'rhs' => 3 ), + array( 'lhs' => 76, 'rhs' => 1 ), + array( 'lhs' => 76, 'rhs' => 3 ), + array( 'lhs' => 66, 'rhs' => 0 ), + array( 'lhs' => 66, 'rhs' => 1 ), array( 'lhs' => 66, 'rhs' => 3 ), - array( 'lhs' => 74, 'rhs' => 1 ), - array( 'lhs' => 74, 'rhs' => 3 ), - array( 'lhs' => 64, 'rhs' => 0 ), - array( 'lhs' => 64, 'rhs' => 1 ), - array( 'lhs' => 64, 'rhs' => 3 ), - array( 'lhs' => 75, 'rhs' => 1 ), - array( 'lhs' => 75, 'rhs' => 3 ), - array( 'lhs' => 76, 'rhs' => 1 ), - array( 'lhs' => 76, 'rhs' => 1 ), - array( 'lhs' => 76, 'rhs' => 1 ), - array( 'lhs' => 62, 'rhs' => 1 ), - array( 'lhs' => 62, 'rhs' => 1 ), array( 'lhs' => 77, 'rhs' => 1 ), + array( 'lhs' => 77, 'rhs' => 3 ), array( 'lhs' => 78, 'rhs' => 1 ), - array( 'lhs' => 59, 'rhs' => 1 ), - array( 'lhs' => 59, 'rhs' => 3 ), - array( 'lhs' => 54, 'rhs' => 1 ), - array( 'lhs' => 81, 'rhs' => 1 ), + array( 'lhs' => 78, 'rhs' => 1 ), + array( 'lhs' => 78, 'rhs' => 1 ), + array( 'lhs' => 63, 'rhs' => 1 ), + array( 'lhs' => 63, 'rhs' => 1 ), array( 'lhs' => 79, 'rhs' => 1 ), array( 'lhs' => 80, 'rhs' => 1 ), - array( 'lhs' => 68, 'rhs' => 1 ), - array( 'lhs' => 70, 'rhs' => 1 ), - array( 'lhs' => 70, 'rhs' => 1 ), - array( 'lhs' => 70, 'rhs' => 1 ), + array( 'lhs' => 60, 'rhs' => 1 ), + array( 'lhs' => 60, 'rhs' => 3 ), + array( 'lhs' => 55, 'rhs' => 1 ), + array( 'lhs' => 64, 'rhs' => 1 ), + array( 'lhs' => 83, 'rhs' => 1 ), + array( 'lhs' => 81, 'rhs' => 1 ), + array( 'lhs' => 82, 'rhs' => 1 ), array( 'lhs' => 70, 'rhs' => 1 ), array( 'lhs' => 72, 'rhs' => 1 ), - array( 'lhs' => 73, 'rhs' => 1 ), - array( 'lhs' => 82, 'rhs' => 1 ), - array( 'lhs' => 82, 'rhs' => 1 ), - array( 'lhs' => 83, 'rhs' => 1 ), - array( 'lhs' => 83, 'rhs' => 1 ), - array( 'lhs' => 83, 'rhs' => 1 ), - array( 'lhs' => 83, 'rhs' => 1 ), - array( 'lhs' => 83, 'rhs' => 1 ), - array( 'lhs' => 83, 'rhs' => 1 ), + array( 'lhs' => 72, 'rhs' => 1 ), + array( 'lhs' => 72, 'rhs' => 1 ), + array( 'lhs' => 72, 'rhs' => 1 ), + array( 'lhs' => 74, 'rhs' => 1 ), + array( 'lhs' => 75, 'rhs' => 1 ), array( 'lhs' => 84, 'rhs' => 1 ), array( 'lhs' => 84, 'rhs' => 1 ), + array( 'lhs' => 85, 'rhs' => 1 ), + array( 'lhs' => 85, 'rhs' => 1 ), + array( 'lhs' => 85, 'rhs' => 1 ), + array( 'lhs' => 85, 'rhs' => 1 ), + array( 'lhs' => 85, 'rhs' => 1 ), + array( 'lhs' => 85, 'rhs' => 1 ), + array( 'lhs' => 86, 'rhs' => 1 ), + array( 'lhs' => 86, 'rhs' => 1 ), + array( 'lhs' => 67, 'rhs' => 1 ), + array( 'lhs' => 67, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), + array( 'lhs' => 65, 'rhs' => 1 ), array( 'lhs' => 65, 'rhs' => 1 ), array( 'lhs' => 65, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), - array( 'lhs' => 63, 'rhs' => 1 ), ); /** @@ -1143,77 +1152,79 @@ static public $yy_action = array( 12 => 12, 13 => 12, 14 => 12, - 18 => 12, - 20 => 12, - 22 => 12, - 24 => 12, - 32 => 12, - 34 => 12, + 15 => 12, + 19 => 12, + 21 => 12, + 23 => 12, + 25 => 12, + 33 => 12, 35 => 12, 36 => 12, 37 => 12, 38 => 12, - 15 => 15, + 39 => 12, 16 => 16, 17 => 17, - 19 => 17, - 21 => 17, - 23 => 17, - 25 => 17, - 26 => 26, + 18 => 18, + 20 => 18, + 22 => 18, + 24 => 18, + 26 => 18, 27 => 27, - 30 => 27, 28 => 28, 31 => 28, 29 => 29, - 33 => 33, - 39 => 39, - 40 => 39, - 41 => 41, + 32 => 29, + 30 => 30, + 34 => 34, + 40 => 40, + 41 => 40, 42 => 42, 43 => 43, - 66 => 43, - 67 => 43, - 68 => 43, - 69 => 43, - 70 => 43, - 71 => 43, - 72 => 43, - 73 => 43, - 74 => 43, - 75 => 43, - 76 => 43, - 77 => 43, - 78 => 43, - 79 => 43, - 80 => 43, - 81 => 43, - 82 => 43, - 83 => 43, - 84 => 43, - 85 => 43, 44 => 44, + 68 => 44, + 69 => 44, + 70 => 44, + 71 => 44, + 72 => 44, + 73 => 44, + 74 => 44, + 75 => 44, + 76 => 44, + 77 => 44, + 78 => 44, + 79 => 44, + 80 => 44, + 81 => 44, + 82 => 44, + 83 => 44, + 84 => 44, + 85 => 44, + 86 => 44, + 87 => 44, 45 => 45, - 47 => 45, - 48 => 45, - 49 => 45, - 50 => 45, - 51 => 45, - 52 => 45, - 53 => 45, - 54 => 45, - 55 => 45, - 56 => 45, - 57 => 45, - 58 => 45, - 59 => 45, - 60 => 45, - 61 => 45, - 62 => 45, - 63 => 45, - 64 => 45, - 65 => 45, 46 => 46, + 47 => 47, + 49 => 47, + 50 => 47, + 51 => 47, + 52 => 47, + 53 => 47, + 54 => 47, + 55 => 47, + 56 => 47, + 57 => 47, + 58 => 47, + 59 => 47, + 60 => 47, + 61 => 47, + 62 => 47, + 63 => 47, + 64 => 47, + 65 => 47, + 66 => 47, + 67 => 47, + 48 => 48, ); /* Beginning here are the reduction cases. A typical example ** follows: @@ -1223,101 +1234,104 @@ static public $yy_action = array( */ #line 29 "oql-parser.y" function yy_r0(){ $this->my_result = $this->yystack[$this->yyidx + 0]->minor; } -#line 1230 "oql-parser.php" +#line 1241 "oql-parser.php" #line 32 "oql-parser.y" function yy_r2(){ - $this->_retvalue = new OqlQuery($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -1]->minor); + $this->_retvalue = new OqlObjectQuery($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -1]->minor); } -#line 1235 "oql-parser.php" +#line 1246 "oql-parser.php" #line 35 "oql-parser.y" function yy_r3(){ - $this->_retvalue = new OqlQuery($this->yystack[$this->yyidx + -4]->minor, $this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -1]->minor); + $this->_retvalue = new OqlObjectQuery($this->yystack[$this->yyidx + -4]->minor, $this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -1]->minor); } -#line 1240 "oql-parser.php" -#line 39 "oql-parser.y" +#line 1251 "oql-parser.php" +#line 48 "oql-parser.y" function yy_r4(){ $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; } -#line 1243 "oql-parser.php" -#line 40 "oql-parser.y" +#line 1254 "oql-parser.php" +#line 49 "oql-parser.y" function yy_r5(){ $this->_retvalue = null; } -#line 1246 "oql-parser.php" -#line 42 "oql-parser.y" +#line 1257 "oql-parser.php" +#line 51 "oql-parser.y" function yy_r6(){ // insert the join statement on top of the existing list array_unshift($this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -1]->minor); // and return the updated array $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; } -#line 1254 "oql-parser.php" -#line 48 "oql-parser.y" +#line 1265 "oql-parser.php" +#line 57 "oql-parser.y" function yy_r7(){ $this->_retvalue = Array($this->yystack[$this->yyidx + 0]->minor); } -#line 1259 "oql-parser.php" -#line 54 "oql-parser.y" +#line 1270 "oql-parser.php" +#line 63 "oql-parser.y" function yy_r9(){ // create an array with one single item $this->_retvalue = new OqlJoinSpec($this->yystack[$this->yyidx + -4]->minor, $this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor); } -#line 1265 "oql-parser.php" -#line 59 "oql-parser.y" +#line 1276 "oql-parser.php" +#line 68 "oql-parser.y" function yy_r10(){ // create an array with one single item $this->_retvalue = new OqlJoinSpec($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor); } -#line 1271 "oql-parser.php" -#line 64 "oql-parser.y" +#line 1282 "oql-parser.php" +#line 73 "oql-parser.y" function yy_r11(){ $this->_retvalue = new BinaryOqlExpression($this->yystack[$this->yyidx + -2]->minor, '=', $this->yystack[$this->yyidx + 0]->minor); } -#line 1274 "oql-parser.php" -#line 66 "oql-parser.y" +#line 1285 "oql-parser.php" +#line 75 "oql-parser.y" function yy_r12(){ $this->_retvalue = $this->yystack[$this->yyidx + 0]->minor; } -#line 1277 "oql-parser.php" -#line 70 "oql-parser.y" - function yy_r15(){ $this->_retvalue = new FunctionOqlExpression($this->yystack[$this->yyidx + -3]->minor, $this->yystack[$this->yyidx + -1]->minor); } -#line 1280 "oql-parser.php" -#line 71 "oql-parser.y" - function yy_r16(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; } -#line 1283 "oql-parser.php" -#line 72 "oql-parser.y" - function yy_r17(){ $this->_retvalue = new BinaryOqlExpression($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor); } -#line 1286 "oql-parser.php" -#line 87 "oql-parser.y" - function yy_r26(){ +#line 1288 "oql-parser.php" +#line 80 "oql-parser.y" + function yy_r16(){ $this->_retvalue = new FunctionOqlExpression($this->yystack[$this->yyidx + -3]->minor, $this->yystack[$this->yyidx + -1]->minor); } +#line 1291 "oql-parser.php" +#line 81 "oql-parser.y" + function yy_r17(){ $this->_retvalue = $this->yystack[$this->yyidx + -1]->minor; } +#line 1294 "oql-parser.php" +#line 82 "oql-parser.y" + function yy_r18(){ $this->_retvalue = new BinaryOqlExpression($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor); } +#line 1297 "oql-parser.php" +#line 97 "oql-parser.y" + function yy_r27(){ $this->_retvalue = new ListOqlExpression($this->yystack[$this->yyidx + -1]->minor); } -#line 1291 "oql-parser.php" -#line 90 "oql-parser.y" - function yy_r27(){ +#line 1302 "oql-parser.php" +#line 100 "oql-parser.y" + function yy_r28(){ $this->_retvalue = array($this->yystack[$this->yyidx + 0]->minor); } -#line 1296 "oql-parser.php" -#line 93 "oql-parser.y" - function yy_r28(){ +#line 1307 "oql-parser.php" +#line 103 "oql-parser.y" + function yy_r29(){ array_push($this->yystack[$this->yyidx + -2]->minor, $this->yystack[$this->yyidx + 0]->minor); $this->_retvalue = $this->yystack[$this->yyidx + -2]->minor; } -#line 1302 "oql-parser.php" -#line 98 "oql-parser.y" - function yy_r29(){ +#line 1313 "oql-parser.php" +#line 108 "oql-parser.y" + function yy_r30(){ $this->_retvalue = array(); } -#line 1307 "oql-parser.php" -#line 109 "oql-parser.y" - function yy_r33(){ $this->_retvalue = new IntervalOqlExpression($this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor); } -#line 1310 "oql-parser.php" -#line 118 "oql-parser.y" - function yy_r39(){ $this->_retvalue = new ScalarOqlExpression($this->yystack[$this->yyidx + 0]->minor); } -#line 1313 "oql-parser.php" -#line 121 "oql-parser.y" - function yy_r41(){ $this->_retvalue = new FieldOqlExpression($this->yystack[$this->yyidx + 0]->minor); } -#line 1316 "oql-parser.php" -#line 122 "oql-parser.y" - function yy_r42(){ $this->_retvalue = new FieldOqlExpression($this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -2]->minor); } -#line 1319 "oql-parser.php" -#line 123 "oql-parser.y" - function yy_r43(){ $this->_retvalue=$this->yystack[$this->yyidx + 0]->minor; } -#line 1322 "oql-parser.php" -#line 125 "oql-parser.y" - function yy_r44(){ +#line 1318 "oql-parser.php" +#line 119 "oql-parser.y" + function yy_r34(){ $this->_retvalue = new IntervalOqlExpression($this->yystack[$this->yyidx + -1]->minor, $this->yystack[$this->yyidx + 0]->minor); } +#line 1321 "oql-parser.php" +#line 128 "oql-parser.y" + function yy_r40(){ $this->_retvalue = new ScalarOqlExpression($this->yystack[$this->yyidx + 0]->minor); } +#line 1324 "oql-parser.php" +#line 131 "oql-parser.y" + function yy_r42(){ $this->_retvalue = new FieldOqlExpression($this->yystack[$this->yyidx + 0]->minor); } +#line 1327 "oql-parser.php" +#line 132 "oql-parser.y" + function yy_r43(){ $this->_retvalue = new FieldOqlExpression($this->yystack[$this->yyidx + 0]->minor, $this->yystack[$this->yyidx + -2]->minor); } +#line 1330 "oql-parser.php" +#line 133 "oql-parser.y" + function yy_r44(){ $this->_retvalue=$this->yystack[$this->yyidx + 0]->minor; } +#line 1333 "oql-parser.php" +#line 136 "oql-parser.y" + function yy_r45(){ $this->_retvalue = new VariableOqlExpression(substr($this->yystack[$this->yyidx + 0]->minor, 1)); } +#line 1336 "oql-parser.php" +#line 138 "oql-parser.y" + function yy_r46(){ if ($this->yystack[$this->yyidx + 0]->minor[0] == '`') { $name = substr($this->yystack[$this->yyidx + 0]->minor, 1, strlen($this->yystack[$this->yyidx + 0]->minor) - 2); @@ -1328,13 +1342,13 @@ static public $yy_action = array( } $this->_retvalue = new OqlName($name, $this->m_iColPrev); } -#line 1335 "oql-parser.php" -#line 137 "oql-parser.y" - function yy_r45(){$this->_retvalue=$this->yystack[$this->yyidx + 0]->minor; } -#line 1338 "oql-parser.php" -#line 138 "oql-parser.y" - function yy_r46(){$this->_retvalue=stripslashes(substr($this->yystack[$this->yyidx + 0]->minor, 1, strlen($this->yystack[$this->yyidx + 0]->minor) - 2)); } -#line 1341 "oql-parser.php" +#line 1349 "oql-parser.php" +#line 150 "oql-parser.y" + function yy_r47(){$this->_retvalue=$this->yystack[$this->yyidx + 0]->minor; } +#line 1352 "oql-parser.php" +#line 151 "oql-parser.y" + function yy_r48(){$this->_retvalue=stripslashes(substr($this->yystack[$this->yyidx + 0]->minor, 1, strlen($this->yystack[$this->yyidx + 0]->minor) - 2)); } +#line 1355 "oql-parser.php" /** * placeholder for the left hand side in a reduce operation. @@ -1449,7 +1463,7 @@ static public $yy_action = array( #line 25 "oql-parser.y" throw new OQLParserException($this->m_sSourceQuery, $this->m_iLine, $this->m_iCol, $this->tokenName($yymajor), $TOKEN); -#line 1457 "oql-parser.php" +#line 1471 "oql-parser.php" } /** @@ -1601,7 +1615,7 @@ throw new OQLParserException($this->m_sSourceQuery, $this->m_iLine, $this->m_iCo } } while ($yymajor != self::YYNOCODE && $this->yyidx >= 0); } -}#line 186 "oql-parser.y" +}#line 199 "oql-parser.y" class OQLParserException extends OQLException @@ -1666,4 +1680,4 @@ class OQLParser extends OQLParserRaw } } -#line 1676 "oql-parser.php" +#line 1690 "oql-parser.php" diff --git a/trunk/core/oql/oql-parser.y b/trunk/core/oql/oql-parser.y index 551a82ada..6d0a5c555 100644 --- a/trunk/core/oql/oql-parser.y +++ b/trunk/core/oql/oql-parser.y @@ -30,12 +30,21 @@ result ::= query(X). { $this->my_result = X; } result ::= condition(X). { $this->my_result = X; } query(A) ::= SELECT class_name(X) join_statement(J) where_statement(W). { - A = new OqlQuery(X, X, W, J); + A = new OqlObjectQuery(X, X, W, J); } query(A) ::= SELECT class_name(X) AS_ALIAS class_name(Y) join_statement(J) where_statement(W). { - A = new OqlQuery(X, Y, W, J); + A = new OqlObjectQuery(X, Y, W, J); } +/* +query(A) ::= SELECT field_id(E) FROM class_name(X) join_statement(J) where_statement(W). { + A = new OqlValueSetQuery(E, X, X, W, J); +} +query(A) ::= SELECT field_id(E) FROM class_name(X) AS_ALIAS class_name(Y) join_statement(J) where_statement(W). { + A = new OqlValueSetQuery(E, X, Y, W, J); +} +*/ + where_statement(A) ::= WHERE condition(C). { A = C;} where_statement(A) ::= . { A = null;} @@ -67,6 +76,7 @@ condition(A) ::= expression_prio4(X). { A = X; } expression_basic(A) ::= scalar(X). { A = X; } expression_basic(A) ::= field_id(X). { A = X; } +expression_basic(A) ::= var_name(X). { A = X; } expression_basic(A) ::= func_name(X) PAR_OPEN arg_list(Y) PAR_CLOSE. { A = new FunctionOqlExpression(X, Y); } expression_basic(A) ::= PAR_OPEN expression_prio4(X) PAR_CLOSE. { A = X; } expression_basic(A) ::= expression_basic(X) list_operator(Y) list(Z). { A = new BinaryOqlExpression(X, Y, Z); } @@ -122,6 +132,9 @@ field_id(A) ::= name(X). { A = new FieldOqlExpression(X); } field_id(A) ::= class_name(X) DOT name(Y). { A = new FieldOqlExpression(Y, X); } class_name(A) ::= name(X). { A=X; } + +var_name(A) ::= VARNAME(X). { A = new VariableOqlExpression(substr(X, 1)); } + name(A) ::= NAME(X). { if (X[0] == '`') { diff --git a/trunk/core/oql/oqlinterpreter.class.inc.php b/trunk/core/oql/oqlinterpreter.class.inc.php index a464413da..ac72a12d9 100644 --- a/trunk/core/oql/oqlinterpreter.class.inc.php +++ b/trunk/core/oql/oqlinterpreter.class.inc.php @@ -35,16 +35,28 @@ class OqlInterpreter return $res; } - public function ParseQuery() + public function ParseObjectQuery() { $oRes = $this->Parse(); - if (!$oRes instanceof OqlQuery) + if (!$oRes instanceof OqlObjectQuery) { - throw new OqlException('Expecting an OQL query', $this->m_sQuery, 0, 0, get_class($oRes), array('OqlQuery')); + throw new OqlException('Expecting an OQL query', $this->m_sQuery, 0, 0, get_class($oRes), array('OqlObjectQuery')); } return $oRes; } +/* + public function ParseValueSetQuery() + { + $oRes = $this->Parse(); + if (!$oRes instanceof OqlValueSetQuery) + { + throw new OqlException('Expecting a value set query', $this->m_sQuery, 0, 0, get_class($oRes), array('OqlValueSetQuery')); + } + return $oRes; + } +*/ + public function ParseExpression() { $oRes = $this->Parse(); diff --git a/trunk/core/oql/oqlquery.class.inc.php b/trunk/core/oql/oqlquery.class.inc.php index ad71950b3..f38cb2e02 100644 --- a/trunk/core/oql/oqlquery.class.inc.php +++ b/trunk/core/oql/oqlquery.class.inc.php @@ -111,6 +111,10 @@ class FieldOqlExpression extends FieldExpression } } +class VariableOqlExpression extends VariableExpression +{ +} + class ListOqlExpression extends ListExpression { } @@ -122,19 +126,38 @@ class FunctionOqlExpression extends FunctionExpression class IntervalOqlExpression extends IntervalExpression { } -class OqlQuery + +abstract class OqlQuery +{ + protected $m_aJoins; // array of OqlJoinSpec + protected $m_oCondition; // condition tree (expressions) + + public function __construct($oCondition = null, $aJoins = null) + { + $this->m_aJoins = $aJoins; + $this->m_oCondition = $oCondition; + } + + public function GetJoins() + { + return $this->m_aJoins; + } + public function GetCondition() + { + return $this->m_oCondition; + } +} + +class OqlObjectQuery extends OqlQuery { protected $m_oClass; protected $m_oClassAlias; - protected $m_aJoins; // array of OqlJoinSpec - protected $m_oCondition; // condition tree (expressions) public function __construct($oClass, $oClassAlias = '', $oCondition = null, $aJoins = null) { $this->m_oClass = $oClass; $this->m_oClassAlias = $oClassAlias; - $this->m_aJoins = $aJoins; - $this->m_oCondition = $oCondition; + parent::__construct($oCondition, $aJoins); } public function GetClass() @@ -154,15 +177,22 @@ class OqlQuery { return $this->m_oClassAlias; } - - public function GetJoins() - { - return $this->m_aJoins; - } - public function GetCondition() - { - return $this->m_oCondition; - } } + +class OqlValueSetQuery extends OqlObjectQuery +{ + protected $m_oSelectExpr; + + public function __construct($oSelectExpr, $oClass, $oClassAlias = '', $oCondition = null, $aJoins = null) + { + $this->m_oSelectExpr = $oSelectExpr; + parent::__construct($oClass, $oClassAlias, $oCondition, $aJoins); + } + + public function GetSelectExpression() + { + return $this->m_oSelectExpr; + } +} ?> diff --git a/trunk/core/sqlquery.class.inc.php b/trunk/core/sqlquery.class.inc.php index 8a55d33c8..1661ed4a2 100644 --- a/trunk/core/sqlquery.class.inc.php +++ b/trunk/core/sqlquery.class.inc.php @@ -28,6 +28,9 @@ class TrueSQLExpression extends TrueExpression class FieldSQLExpression extends FieldExpression { } +class VariableSQLExpression extends VariableExpression +{ +} @@ -212,7 +215,7 @@ class SQLQuery } // Interface, build the SQL query - public function RenderSelect($aOrderBy = array()) + public function RenderSelect($aOrderBy = array(), $aArgs = array()) { // The goal will be to complete the lists as we build the Joins $aFrom = array(); @@ -224,7 +227,7 @@ class SQLQuery $sSelect = self::ClauseSelect($aFields); $sFrom = self::ClauseFrom($aFrom); - $sWhere = self::ClauseWhere($oCondition); + $sWhere = self::ClauseWhere($oCondition, $aArgs); $sOrderBy = self::ClauseOrderBy($aOrderBy); if (!empty($sOrderBy)) { @@ -294,9 +297,9 @@ class SQLQuery return $sSetValues; } - private static function ClauseWhere($oConditionExpr) + private static function ClauseWhere($oConditionExpr, $aArgs = array()) { - return $oConditionExpr->Render(); + return $oConditionExpr->Render($aArgs); } private static function ClauseOrderBy($aOrderBy) diff --git a/trunk/core/valuesetdef.class.inc.php b/trunk/core/valuesetdef.class.inc.php index c541683cc..2adae3aff 100644 --- a/trunk/core/valuesetdef.class.inc.php +++ b/trunk/core/valuesetdef.class.inc.php @@ -104,14 +104,15 @@ class ValueSetObjects extends ValueSetDefinition { $this->m_aValues = array(); - $oFilter = DBObjectSearch::FromSibuSQL($this->m_sFilterExpr, $aArgs); + $oFilter = DBObjectSearch::FromSibusQL($this->m_sFilterExpr, $aArgs); if (!$oFilter) return false; - if (empty($this->m_sValueAttCode)) - { - $this->m_sValueAttCode = MetaModel::GetNameAttributeCode($oFilter->GetClass()); - } - $oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy); + if (empty($this->m_sValueAttCode)) + { + $this->m_sValueAttCode = MetaModel::GetNameAttributeCode($oFilter->GetClass()); + } + + $oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs); while ($oObject = $oObjects->Fetch()) { $this->m_aValues[$oObject->GetKey()] = $oObject->GetAsHTML($this->m_sValueAttCode); @@ -235,4 +236,35 @@ class ValueSetEnum extends ValueSetDefinition } } + +/** + * Data model classes + * + * @package iTopORM + * @author Romain Quetiez + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.itop.com + * @since 1.0 + * @version $itopversion$ + */ +class ValueSetEnumClasses extends ValueSetEnum +{ + public function __construct($sCategory = '', $sAdditionalValues = '') + { + // First, build it from the series of additional values + parent::__construct($sAdditionalValues); + + // Second: add the list of classes + foreach (MetaModel::GetClasses($sCategory) as $sClass) + { + $this->m_aValues[$sClass] = MetaModel::GetName($sClass); + } + } + + protected function LoadValues($aArgs) + { + return true; + } +} + ?> diff --git a/trunk/pages/testlist.inc.php b/trunk/pages/testlist.inc.php index db9b448d8..fcdb246cd 100644 --- a/trunk/pages/testlist.inc.php +++ b/trunk/pages/testlist.inc.php @@ -75,7 +75,7 @@ class TestOQLParser extends TestFunction $oOql = new OqlInterpreter($sQuery); try { - $oTrash = $oOql->ParseQuery(); + $oTrash = $oOql->Parse(); // Not expecting a given format, otherwise use ParseExpression/ParseObjectQuery/ParseValueSetQuery MyHelpers::var_dump_html($oTrash, true); } catch (OQLException $OqlException) @@ -687,7 +687,7 @@ class TestQueriesOnFarm extends TestBizModel try { //$oOql = new OqlInterpreter($sQuery); - //$oTrash = $oOql->ParseQuery(); + //$oTrash = $oOql->ParseObjectQuery(); //MyHelpers::var_dump_html($oTrash, true); $oMyFilter = DBObjectSearch::FromOQL($sQuery); } diff --git a/trunk/pages/usermanagement_classproj.php b/trunk/pages/usermanagement_classproj.php new file mode 100644 index 000000000..a2e8f7195 --- /dev/null +++ b/trunk/pages/usermanagement_classproj.php @@ -0,0 +1,90 @@ +Fetch()) + { + $aDimensions[$oDimension->GetKey()] = $oDimension; + } + + // Load the class projections for a further usage + // + $aClassProj = array(); + $oClassProjSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ClassProjection")); + while ($oClassProj = $oClassProjSet->Fetch()) + { + $aClassProjs[$oClassProj->Get('class')][$oClassProj->Get('dimensionid')] = $oClassProj; + } + + // Setup display structure + // + $aDisplayConfig = array(); + $aDisplayConfig['class'] = array('label' => 'Class', 'description' => 'Class'); + $aDisplayConfig['object'] = array('label' => 'Object', 'description' => 'Projected object'); + foreach ($aDimensions as $iDimension => $oDimension) + { + $aDisplayConfig['dim'.$oDimension->GetKey()] = array('label' => $oDimension->GetName(), 'description' => $oDimension->Get('description')); + } + + // Load objects + // + $aDisplayData = array(); + $oObjectSet = new DBObjectSet(DBObjectSearch::FromOQL($sScope)); + $sClass = $oObjectSet->GetClass(); + while ($oObject = $oObjectSet->Fetch()) + { + $aObjectProj = array(); + $oObjectProj['class'] = $sClass; + $oObjectProj['object'] = $oObject->GetName(); + foreach ($aDimensions as $iDimension => $oDimension) + { + // #@# to be moved, may be time consuming + $oDimension->CheckProjectionSpec($aClassProjs[$sClass][$iDimension]); + + $aValues = $aClassProjs[$sClass][$iDimension]->ProjectObject($oObject); + $sValues = implode(', ', $aValues); + $oObjectProj['dim'.$oDimension->GetKey()] = htmlentities($sValues); + } + + $aDisplayData[] = $oObjectProj; + } + + $oPage->table($aDisplayConfig, $aDisplayData); + +//$oPage->SetCurrentTab('Attributes'); +//$oPage->p("[All classes]"); +//$oPage->add("\n"); + +} + + +require_once('../application/loginwebpage.class.inc.php'); +login_web_page::DoLogin(); // Check user rights and prompt if needed + +// Display the menu on the left +$oContext = new UserContext(); +$oAppContext = new ApplicationContext(); +$iActiveNodeId = utils::ReadParam('menu', -1); +$currentOrganization = utils::ReadParam('org_id', 1); +$sScope = utils::ReadParam('scope', 'SELECT bizDevice'); + +$oPage = new iTopWebPage("iTop user management - class projections", $currentOrganization); +$oPage->no_cache(); + +ComputeProjections($oPage, $sScope); +$oPage->output(); + +?> diff --git a/trunk/pages/usermanagement_profileproj.php b/trunk/pages/usermanagement_profileproj.php new file mode 100644 index 000000000..a7497d0e0 --- /dev/null +++ b/trunk/pages/usermanagement_profileproj.php @@ -0,0 +1,100 @@ +Fetch()) + { + $aProfiles[$oProfile->GetKey()] = $oProfile; + } + + // Load the dimensions for a further usage + // + $aDimensions = array(); + $oDimensionSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Dimensions")); + while ($oDimension = $oDimensionSet->Fetch()) + { + $aDimensions[$oDimension->GetKey()] = $oDimension; + } + + // Load the profile projections for a further usage + // + $aProPro = array(); + $oProProSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_ProfileProjection")); + while ($oProPro = $oProProSet->Fetch()) + { + $aProPros[$oProPro->Get('profileid')][$oProPro->Get('dimensionid')] = $oProPro; + } + + // Setup display structure + // + $aDisplayConfig = array(); + $aDisplayConfig['user'] = array('label' => 'User', 'description' => 'User concerned by the projection'); + $aDisplayConfig['profile'] = array('label' => 'Profile', 'description' => 'Profile in which the projection is specified'); + foreach ($aDimensions as $iDimension => $oDimension) + { + $aDisplayConfig['dim'.$oDimension->GetKey()] = array('label' => $oDimension->GetName(), 'description' => $oDimension->Get('description')); + } + + // Load users, and create a record per couple user/profile + // + $aDisplayData = array(); + $oUserSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_Users")); + while ($oUser = $oUserSet->Fetch()) + { + $oUserProfileSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT URP_UserProfile WHERE userid = :user->id"), array(), array('user' => $oUser)); + while ($oUserProfile = $oUserProfileSet->Fetch()) + { + $iProfile = $oUserProfile->Get('profileid'); + $oProfile = $aProfiles[$iProfile]; + + $aUserProfileProj = array(); + $aUserProfileProj['user'] = $oUser->GetName(); + $aUserProfileProj['profile'] = $oProfile->GetName(); + foreach ($aDimensions as $iDimension => $oDimension) + { + // #@# to be moved, may be time consuming + $oDimension->CheckProjectionSpec($aProPros[$iProfile][$iDimension]); + + $aValues = $aProPros[$iProfile][$iDimension]->ProjectUser($oUser); + $sValues = implode(', ', $aValues); + $aUserProfileProj['dim'.$oDimension->GetKey()] = htmlentities($sValues); + } + + $aDisplayData[] = $aUserProfileProj; + } + } + + $oPage->table($aDisplayConfig, $aDisplayData); + +//$oPage->SetCurrentTab('Attributes'); +//$oPage->p("[All classes]"); +//$oPage->add("\n"); + +} + + +require_once('../application/loginwebpage.class.inc.php'); +login_web_page::DoLogin(); // Check user rights and prompt if needed + +// Display the menu on the left +$oContext = new UserContext(); +$oAppContext = new ApplicationContext(); +$iActiveNodeId = utils::ReadParam('menu', -1); +$currentOrganization = utils::ReadParam('org_id', 1); + +$oPage = new iTopWebPage("iTop user management - profile projections", $currentOrganization); +$oPage->no_cache(); + +ComputeProjections($oPage); +$oPage->output(); + +?>