public override IEnumerable<ObjectUUID> IndexSingleOperation(AAttributeIndex myIndex, ADBBaseObject myOperationValue, AttributeUUID myAttributeUUID, TypesOfBinaryExpression typeOfBinExpr, DBContext dbContext) { IndexKey lookup = new IndexKey(myAttributeUUID, myOperationValue, myIndex.IndexKeyDefinition); var currentType = dbContext.DBTypeManager.GetTypeByUUID(myIndex.IndexRelatedTypeUUID); var result = myIndex.Contains(lookup, currentType, dbContext); if (result.Value) { var interestingUUIDs = myIndex.GetValues(lookup, currentType, dbContext); foreach (var aIndexValue in myIndex.GetAllValues(currentType, dbContext)) { foreach (var aUUID in aIndexValue) { if (!interestingUUIDs.Contains(aUUID)) { yield return aUUID; } } } } else { foreach (var aIndexValue in myIndex.GetKeyValues(currentType, dbContext).Select(kv => kv.Value)) { foreach (var aUUID in aIndexValue) { yield return aUUID; } } } yield break; }
public override IEnumerable<ObjectUUID> IndexOperation(AAttributeIndex myIndex, TupleDefinition myTuple, TypesOfBinaryExpression typeOfBinExpr, DBContext dbContext) { if (myTuple.Count() != 2) { throw new GraphDBException(new Error_InvalidInRangeInterval(2, myTuple.Count())); } var currentType = dbContext.DBTypeManager.GetTypeByUUID(myIndex.IndexRelatedTypeUUID); #region As soon as the index supports ranges use them!! //limits var fromKey = new IndexKey(myIndex.IndexKeyDefinition.IndexKeyAttributeUUIDs[0], (myTuple.ElementAt(0).Value as ValueDefinition).Value, myIndex.IndexKeyDefinition); var toKey = new IndexKey(myIndex.IndexKeyDefinition.IndexKeyAttributeUUIDs[0], (myTuple.ElementAt(1).Value as ValueDefinition).Value, myIndex.IndexKeyDefinition); switch (myTuple.KindOfTuple) { case KindOfTuple.Inclusive: return myIndex.InRange(fromKey, toKey, true, true, currentType, dbContext); case KindOfTuple.LeftExclusive: return myIndex.InRange(fromKey, toKey, false, true, currentType, dbContext); case KindOfTuple.RightExclusive: return myIndex.InRange(fromKey, toKey, true, false, currentType, dbContext); case KindOfTuple.Exclusive: return myIndex.InRange(fromKey, toKey, false, false, currentType, dbContext); default: throw new GraphDBException(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } #endregion }
public Error_InvalidBinaryExpression(ABinaryCompareOperator myOperator, Tuple<IDChainDefinition, IDChainDefinition> myIDChainDefinitions, Tuple<AExpressionDefinition, AExpressionDefinition> myOperands, TypesOfBinaryExpression myTypeOfBinaryOperation) { Operator = myOperator; IDChainDefinitions = myIDChainDefinitions; Operands = myOperands; TypeOfBinaryOperation = myTypeOfBinaryOperation; BinaryExpression = null; }
public override Exceptional<AOperationDefinition> SimpleOperation(AOperationDefinition left, AOperationDefinition right, TypesOfBinaryExpression myTypeOfBinaryExpression) { if (!(left is ValueDefinition && right is ValueDefinition)) { return new Exceptional<AOperationDefinition>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } return SimpleOperation((ValueDefinition)left, (ValueDefinition)right); }
public override IEnumerable<ObjectUUID> IndexSingleOperation(AAttributeIndex myIndex, ADBBaseObject myOperationValue, AttributeUUID myAttributeUUID, TypesOfBinaryExpression typeOfBinExpr, DBContext dbContext) { var myIndeyKey = new IndexKey(myAttributeUUID, myOperationValue, myIndex.IndexKeyDefinition); var currentType = dbContext.DBTypeManager.GetTypeByUUID(myIndex.IndexRelatedTypeUUID); if (myIndex.Contains(myIndeyKey, currentType, dbContext)) { foreach (var aUUID in myIndex.GetValues(myIndeyKey, currentType, dbContext)) { yield return aUUID; } } yield break; }
public override Exceptional<AOperationDefinition> SimpleOperation(AOperationDefinition left, AOperationDefinition right, TypesOfBinaryExpression myTypeOfBinaryExpression) { if (left is ValueDefinition && right is ValueDefinition) return SimpleOperation((ValueDefinition)left, (ValueDefinition)right); /* 3 - [3,5,7] ??? if (left is AtomValue && right is TupleValue) return SimpleOperation((AtomValue)left, (TupleValue)right); */ if (left is TupleDefinition && right is ValueDefinition) return SimpleOperation((ValueDefinition)right, (TupleDefinition)left); if (left is TupleDefinition && right is TupleDefinition) return SimpleOperation((TupleDefinition)right, (TupleDefinition)left); return new Exceptional<AOperationDefinition>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); }
public virtual IEnumerable<ObjectUUID> IndexSingleOperation(AAttributeIndex myIndex, ADBBaseObject myOperationValue, AttributeUUID myAttributeUUID, TypesOfBinaryExpression typeOfBinExpr, DBContext dbContext) { foreach (var keyValPair in myIndex.GetKeyValues(dbContext.DBTypeManager.GetTypeByUUID(myIndex.IndexRelatedTypeUUID), dbContext)) { var res = Compare(keyValPair.Key.IndexKeyValues[0], myOperationValue); if (res.Failed()) { throw new GraphDBException(res.PushIError(new Error_InvalidIndexOperation(myIndex.IndexName, keyValPair.Key.IndexKeyValues[0].Value, myOperationValue.Value)).IErrors); } if (res.Value) { foreach (var aUUID in keyValPair.Value) { yield return aUUID; } } } yield break; }
public virtual IEnumerable<ObjectUUID> IndexOperationReloaded(AAttributeIndex myIndex, List<Tuple<AttributeUUID, ADBBaseObject>> myOperationValues, TypesOfBinaryExpression typeOfBinExpr) { throw new GraphDBException(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); }
/// <summary> /// Finds matching result corresponding to a binary expression. /// </summary> /// <param name="myLeftValueObject">The left value of a binary expression.</param> /// <param name="myRightValueObject">The right value of a binary expression.</param> /// <param name="currentTypeDefinitione"></param> /// <param name="dbContext">The TypeManager of the database.</param> /// <param name="typeOfBinExpr">The type of the binary expression.</param> /// <param name="associativity">The associativity of the binary expression.</param> /// <param name="referenceList"></param> /// <param name="queryCache">The per query DBObject/BackwardEdge cache.</param> /// <returns></returns> public override Exceptional<IExpressionGraph> TypeOperation(AExpressionDefinition myLeftValueObject, AExpressionDefinition myRightValueObject, DBContext dbContext, TypesOfBinaryExpression typeOfBinExpr, TypesOfAssociativity associativity, IExpressionGraph resultGr, Boolean aggregateAllowed = true) { #region Data //list of errors List<GraphDBError> errors = new List<GraphDBError>(); //DataContainer for all data that is used by a binary expression/comparer Exceptional<DataContainer> data; //the index of the left attribute IEnumerable<Tuple<GraphDBType, AAttributeIndex>> leftIndex = null; //the index of the right attribute IEnumerable<Tuple<GraphDBType, AAttributeIndex>> rightIndex = null; #endregion #region extract data //data extraction with an eye on the type of the binary expression switch (typeOfBinExpr) { case TypesOfBinaryExpression.Atom: //sth like 3 = 4 #region Get Atom data //no further data has to be generated //data = new DataContainer(null, new Tuple<Object, Object>(myLeftValueObject, myRightValueObject), null); data = new Exceptional<DataContainer>(); #endregion break; case TypesOfBinaryExpression.LeftComplex: //sth like U.Age = 21 #region Get LeftComplex data data = ExtractData(myLeftValueObject, myRightValueObject, ref typeOfBinExpr, dbContext.DBObjectCache, dbContext.SessionSettings, dbContext, aggregateAllowed); if (!data.Success()) { return new Exceptional<IExpressionGraph>(data); } #endregion break; case TypesOfBinaryExpression.RightComplex: //sth like 21 = U.Age #region Get RightComplex data data = ExtractData(myRightValueObject, myLeftValueObject, ref typeOfBinExpr, dbContext.DBObjectCache, dbContext.SessionSettings, dbContext, aggregateAllowed); if (!data.Success()) { return new Exceptional<IExpressionGraph>(data); } #endregion break; case TypesOfBinaryExpression.Complex: //sth like U.Age = F.Alter #region Get Complex data var leftData = ExtractData(myLeftValueObject, myRightValueObject, ref typeOfBinExpr, dbContext.DBObjectCache, dbContext.SessionSettings, dbContext, aggregateAllowed); if (!leftData.Success()) { return new Exceptional<IExpressionGraph>(leftData); } var rightData = ExtractData(myRightValueObject, myLeftValueObject, ref typeOfBinExpr, dbContext.DBObjectCache, dbContext.SessionSettings, dbContext, aggregateAllowed); if (!rightData.Success()) { return new Exceptional<IExpressionGraph>(rightData); } if (typeOfBinExpr == TypesOfBinaryExpression.Unknown) { typeOfBinExpr = SetTypeOfBinaryExpression(leftData, rightData); switch (typeOfBinExpr) { case TypesOfBinaryExpression.Atom: data = new Exceptional<DataContainer>(new DataContainer(new Tuple<IDChainDefinition, IDChainDefinition>(null, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(leftData.Value.Operands.Item1, leftData.Value.Operands.Item1), new Tuple<AExpressionDefinition, AExpressionDefinition>(null, null))); break; case TypesOfBinaryExpression.LeftComplex: data = new Exceptional<DataContainer>(new DataContainer(new Tuple<IDChainDefinition, IDChainDefinition>(leftData.Value.IDChainDefinitions.Item1, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(rightData.Value.Operands.Item1, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(null, null))); break; case TypesOfBinaryExpression.RightComplex: data = new Exceptional<DataContainer>(new DataContainer(new Tuple<IDChainDefinition, IDChainDefinition>(rightData.Value.IDChainDefinitions.Item1, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(leftData.Value.Operands.Item1, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(null, null))); break; case TypesOfBinaryExpression.Complex: case TypesOfBinaryExpression.Unknown: default: throw new GraphDBException(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } } else { data = new Exceptional<DataContainer>(JoinData(leftData.Value, rightData.Value)); } #endregion break; default: throw new ArgumentException(); } #region handle errors if (data.Failed()) { return new Exceptional<IExpressionGraph>(data); } #endregion #endregion #region get indexes switch (typeOfBinExpr) { case TypesOfBinaryExpression.LeftComplex: leftIndex = GetIndex(data.Value.IDChainDefinitions.Item1.LastAttribute, dbContext, data.Value.IDChainDefinitions.Item1.LastType, data.Value.Extraordinaries.Item1); break; case TypesOfBinaryExpression.RightComplex: //data.IdNodes.TupelElement1 is correct, because of correct handling in extract data (data.IdNodes.TupelElement2 should be null here) rightIndex = GetIndex(data.Value.IDChainDefinitions.Item1.LastAttribute, dbContext, data.Value.IDChainDefinitions.Item1.LastType, data.Value.Extraordinaries.Item1); break; case TypesOfBinaryExpression.Complex: //both indexe have to be catched leftIndex = GetIndex(data.Value.IDChainDefinitions.Item1.LastAttribute, dbContext, data.Value.IDChainDefinitions.Item1.LastType, data.Value.Extraordinaries.Item1); rightIndex = GetIndex(data.Value.IDChainDefinitions.Item2.LastAttribute, dbContext, data.Value.IDChainDefinitions.Item2.LastType, data.Value.Extraordinaries.Item1); break; } #endregion //time to compare some things Exceptional<Boolean> matchDataResult = null; if (IsValidIndexOperation(data.Value, dbContext, typeOfBinExpr)) { #region match data switch (typeOfBinExpr) { case TypesOfBinaryExpression.Atom: #region Atom //do nothing 3 = 3 (or 2 != 3) doesnt bother U #endregion break; case TypesOfBinaryExpression.LeftComplex: #region LeftComplex matchDataResult = MatchData(data.Value, dbContext, dbContext.DBObjectCache, typeOfBinExpr, leftIndex, resultGr, dbContext.SessionSettings); #endregion break; case TypesOfBinaryExpression.RightComplex: #region RightComplex matchDataResult = MatchData(data.Value, dbContext, dbContext.DBObjectCache, typeOfBinExpr, rightIndex, resultGr, dbContext.SessionSettings); #endregion break; case TypesOfBinaryExpression.Complex: #region Complex matchDataResult = MatchComplexData(associativity, data.Value, dbContext, dbContext.DBObjectCache, typeOfBinExpr, leftIndex, rightIndex, ref errors, ref resultGr, dbContext.SessionSettings); #endregion break; } #endregion } else { return new Exceptional<IExpressionGraph>(new Error_InvalidBinaryExpression(this, data.Value.IDChainDefinitions, data.Value.Operands, typeOfBinExpr)); } if (matchDataResult != null && matchDataResult.Failed()) return new Exceptional<IExpressionGraph>(matchDataResult); else return new Exceptional<IExpressionGraph>(resultGr); }
public override bool IsValidIndexOperation(DataContainer data, DBContext myTypeManager, TypesOfBinaryExpression typeOfBinExpr) { switch (typeOfBinExpr) { case TypesOfBinaryExpression.LeftComplex: if (data.Operands.Item1 is TupleDefinition) { return true; } else { return false; } case TypesOfBinaryExpression.RightComplex: if ((data.Operands.Item1 is ValueDefinition) || data.Operands.Item1 is TupleDefinition) { return true; } else { return false; } case TypesOfBinaryExpression.Complex: case TypesOfBinaryExpression.Atom: return true; case TypesOfBinaryExpression.Unknown: default: throw new GraphDBException(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } }
/// <summary> /// This method checks and integrates a DBObjectStream into the result graph. /// </summary> /// <param name="myData">The DataContainer.</param> /// <param name="myTypeManager">The TypeManager of the database.</param> /// <param name="myQueryCache">The current query cache.</param> /// <param name="myTypeOfBinExpr">The kind of the binary expression.</param> /// <param name="myResultGraph">The resulting IExpressionGraph.</param> /// <param name="myDBObjectStream">The DBObjectStream.</param> private Exceptional<object> CheckAndIntegrateDBObjectStream(DataContainer myData, DBContext myTypeManager, DBObjectCache myQueryCache, TypesOfBinaryExpression myTypeOfBinExpr, IExpressionGraph myResultGraph, DBObjectStream myDBObjectStream, LevelKey myLevelKey, SessionSettings mySessionToken) { //get the operand var operand = GetOperand(myData.IDChainDefinitions.Item1, myData.Extraordinaries.Item1, myTypeManager, myDBObjectStream, myQueryCache, mySessionToken); if(operand == null) { return new Exceptional<object>(); } if (operand.Failed()) { return new Exceptional<object>(operand); } Exceptional<AOperationDefinition> tempSimpleOperationResult; switch (myTypeOfBinExpr) { case TypesOfBinaryExpression.LeftComplex: tempSimpleOperationResult = this.SimpleOperation(operand.Value, ((AOperationDefinition)myData.Operands.Item1), myTypeOfBinExpr); break; case TypesOfBinaryExpression.RightComplex: tempSimpleOperationResult = this.SimpleOperation(((AOperationDefinition)myData.Operands.Item1), operand.Value, myTypeOfBinExpr); break; case TypesOfBinaryExpression.Complex: case TypesOfBinaryExpression.Atom: default: throw new ArgumentException(); } if (tempSimpleOperationResult.Failed()) { return new Exceptional<object>(tempSimpleOperationResult); } var tempOperatorResult = ((ValueDefinition)tempSimpleOperationResult.Value); if ((Boolean)tempOperatorResult.Value.Value) { IntegrateInGraph(myDBObjectStream, myResultGraph, myLevelKey, myTypeManager, myQueryCache); } //else //{ // /// We need to add an empty level in case, the DBO should not be integerated. Otherwise the select does not know, either the level was never touched or // /// not added due to an expression // ExcludeFromGraph(myDBObjectStream, myResultGraph, myLevelKey, myTypeManager, myQueryCache); //} return new Exceptional<object>(); }
/// <summary> /// Finds matching result corresponding to a binary expression. /// </summary> /// <param name="myLeftValueObject">The left value of a binary expression.</param> /// <param name="myRightValueObject">The right value of a binary expression.</param> /// <param name="myPluginManager"></param> /// <param name="myGraphDB"></param> /// <param name="mySecurityToken"></param> /// <param name="myTransactionToken"></param> /// <param name="typeOfBinExpr">Type of the binary expression.</param> /// <param name="resultGr"></param> /// <param name="mytypesOfOpertators"></param> /// <param name="myOperator">The binary operator.</param> /// <param name="myExpressionIndex">The name of the index which should be used for the expression.</param> /// <param name="aggregateAllowed"></param> /// <returns>An expression graph.</returns> public static IExpressionGraph TypeOperation(AExpressionDefinition myLeftValueObject, AExpressionDefinition myRightValueObject, GQLPluginManager myPluginManager, IGraphDB myGraphDB, SecurityToken mySecurityToken, Int64 myTransactionToken, TypesOfBinaryExpression typeOfBinExpr, IExpressionGraph resultGr, TypesOfOperators mytypesOfOpertators, BinaryOperator myOperator, String myExpressionIndex, Boolean aggregateAllowed = true) { #region Data //DataContainer for all data that is used by a binary expression/comparer DataContainer data; #endregion #region extract data //data extraction with an eye on the type of the binary expression switch (typeOfBinExpr) { case TypesOfBinaryExpression.Atom: //sth like 3 = 4 #region Get Atom data //no further data has to be generated //data = new DataContainer(null, new Tuple<Object, Object>(myLeftValueObject, myRightValueObject), null); data = new DataContainer(); #endregion break; case TypesOfBinaryExpression.LeftComplex: //sth like U.Age = 21 #region Get LeftComplex data data = ExtractData(myLeftValueObject, myRightValueObject, ref typeOfBinExpr, myPluginManager, myGraphDB, mySecurityToken, myTransactionToken, aggregateAllowed); #endregion break; case TypesOfBinaryExpression.RightComplex: //sth like 21 = U.Age #region Get RightComplex data data = ExtractData(myRightValueObject, myLeftValueObject, ref typeOfBinExpr, myPluginManager, myGraphDB, mySecurityToken, myTransactionToken, aggregateAllowed); #endregion break; case TypesOfBinaryExpression.Complex: //sth like U.Age = F.Alter #region Get Complex data var leftData = ExtractData(myLeftValueObject, myRightValueObject, ref typeOfBinExpr, myPluginManager, myGraphDB, mySecurityToken, myTransactionToken, aggregateAllowed); var rightData = ExtractData(myRightValueObject, myLeftValueObject, ref typeOfBinExpr, myPluginManager, myGraphDB, mySecurityToken, myTransactionToken, aggregateAllowed); if (typeOfBinExpr == TypesOfBinaryExpression.Unknown) { typeOfBinExpr = SetTypeOfBinaryExpression(leftData, rightData); switch (typeOfBinExpr) { case TypesOfBinaryExpression.Atom: data = new DataContainer(new Tuple <IDChainDefinition, IDChainDefinition>(null, null), new Tuple <AExpressionDefinition, AExpressionDefinition>(leftData.Operands.Item1, leftData.Operands.Item1), new Tuple <AExpressionDefinition, AExpressionDefinition>(null, null)); break; case TypesOfBinaryExpression.LeftComplex: data = new DataContainer(new Tuple <IDChainDefinition, IDChainDefinition>(leftData.IDChainDefinitions.Item1, null), new Tuple <AExpressionDefinition, AExpressionDefinition>(rightData.Operands.Item1, null), new Tuple <AExpressionDefinition, AExpressionDefinition>(null, null)); break; case TypesOfBinaryExpression.RightComplex: data = new DataContainer(new Tuple <IDChainDefinition, IDChainDefinition>(rightData.IDChainDefinitions.Item1, null), new Tuple <AExpressionDefinition, AExpressionDefinition>(leftData.Operands.Item1, null), new Tuple <AExpressionDefinition, AExpressionDefinition>(null, null)); break; case TypesOfBinaryExpression.Complex: case TypesOfBinaryExpression.Unknown: default: throw new NotImplementedQLException(""); } } else { data = JoinData(leftData, rightData); } #endregion break; default: throw new ArgumentException(); } #endregion #region match data switch (typeOfBinExpr) { case TypesOfBinaryExpression.Atom: #region Atom //do nothing 3 = 3 (or 2 != 3) doesnt bother U #endregion break; case TypesOfBinaryExpression.LeftComplex: #region LeftComplex MatchData(data, resultGr, myGraphDB, mySecurityToken, myTransactionToken, mytypesOfOpertators, myOperator, myExpressionIndex); #endregion break; case TypesOfBinaryExpression.RightComplex: #region RightComplex MatchData(data, resultGr, myGraphDB, mySecurityToken, myTransactionToken, mytypesOfOpertators, myOperator, myExpressionIndex); #endregion break; case TypesOfBinaryExpression.Complex: #region Complex throw new NotImplementedQLException(""); #endregion } #endregion return(resultGr); }
public override Exceptional<IExpressionGraph> TypeOperation(AExpressionDefinition myLeftValueObject, AExpressionDefinition myRightValueObject, DBContext dbContext, TypesOfBinaryExpression typeOfBinExpr, TypesOfAssociativity associativity, IExpressionGraph result, Boolean aggregateAllowed = true) { return new Exceptional<IExpressionGraph>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); }
/// <summary> /// Extracts data for a binary expression /// </summary> /// <param name="myComplexValue">The complex part of the binary expression.</param> /// <param name="mySimpleValue">The simple/atomic part of the expression.</param> /// <param name="errors">The list of errors.</param> /// <param name="typeOfBinExpr">The kind of the binary expression</param> /// <returns>A data tuple.</returns> private static DataContainer ExtractData(AExpressionDefinition myComplexValue, AExpressionDefinition mySimpleValue, ref TypesOfBinaryExpression typeOfBinExpr, GQLPluginManager myPluginManager, IGraphDB myGraphDB, SecurityToken mySecurityToken, Int64 myTransactionToken, Boolean aggregateAllowed) { #region data //the complex IDNode (sth. like U.Age or Count(U.Friends)) IDChainDefinition complexIDNode = null; //the value that is on the opposite of the complex IDNode AExpressionDefinition simpleValue = null; //a complex IDNode may result in a complexValue (i.e. Count(U.Friends) --> 3) AExpressionDefinition complexValue = null; //reference to former myComplexValue AExpressionDefinition extraordinaryValue = null; #endregion #region extraction if (myComplexValue is IDChainDefinition) { #region IDNode #region Data complexIDNode = (IDChainDefinition)myComplexValue; complexIDNode.Validate(myPluginManager, myGraphDB, mySecurityToken, myTransactionToken, false); if (complexIDNode.Any(id => id is ChainPartFuncDefinition)) { if (complexIDNode.Edges == null || complexIDNode.Edges.Count == 0) { #region parameterless function var fcn = (complexIDNode.First(id => id is ChainPartFuncDefinition) as ChainPartFuncDefinition); // somes functions (aggregates) like SUM are not valid for where expressions, though they are not resolved if (fcn.Function == null) { throw new FunctionDoesNotExistException(fcn.FuncName); } FuncParameter pResult = fcn.Function.ExecFunc(null, null, null, myGraphDB, mySecurityToken, myTransactionToken); //simpleValue = new AtomValue(fcn.Function.TypeOfResult, ((FuncParameter)pResult.Value).Value); //the new simple value extraced from the function simpleValue = new ValueDefinition(((FuncParameter)pResult).Value); typeOfBinExpr = TypesOfBinaryExpression.Unknown; //we do not know if we are left or right associated complexIDNode = null; //we resolved it... so it's null #endregion } else { //extraordinaryValue = (complexIDNode.First(id => id is ChainPartFuncDefinition) as ChainPartFuncDefinition); extraordinaryValue = complexIDNode; if (mySimpleValue is ValueDefinition) { simpleValue = mySimpleValue; } } } else { if (mySimpleValue is ValueDefinition) { try { if (complexIDNode.IsUndefinedAttribute) { throw new VertexAttributeIsNotDefinedException(complexIDNode.UndefinedAttribute); } simpleValue = GetCorrectValueDefinition(complexIDNode.LastAttribute, complexIDNode.LastType, ((ValueDefinition)mySimpleValue)); } catch (FormatException) { throw new DataTypeDoesNotMatchException(((IPropertyDefinition)complexIDNode.LastAttribute).BaseType.Name, ((ValueDefinition)mySimpleValue).Value.GetType().Name); } } else { if (mySimpleValue is TupleDefinition) { ((TupleDefinition)mySimpleValue).ConvertToAttributeType(myPluginManager, complexIDNode.LastAttribute, myGraphDB, mySecurityToken, myTransactionToken); simpleValue = mySimpleValue; } } } #endregion #endregion } else if (myComplexValue is TupleDefinition) { #region TupleSetNode complexValue = ((TupleDefinition)myComplexValue); simpleValue = mySimpleValue; typeOfBinExpr = TypesOfBinaryExpression.Atom; #endregion } else if (myComplexValue is AggregateDefinition) { #region AggregateNode if (aggregateAllowed) { if (((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters.Count != 1) { throw new GQLAggregateArgumentException("An aggregate must have exactly one expression."); } if (!(((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters[0] is IDChainDefinition)) { throw new GQLAggregateArgumentException("An aggregate must have exactly one IDNode."); } #region Data complexIDNode = (((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters[0] as IDChainDefinition); if (complexIDNode == null) { throw new InvalidIDNodeException("Only single IDNodes are currently allowed in aggregates!"); } #endregion #region values simpleValue = mySimpleValue; extraordinaryValue = myComplexValue; #endregion } else { throw new AggregateNotAllowedException(((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Aggregate.PluginShortName); } #endregion } else { throw new NotImplementedQLException(""); } #endregion return new DataContainer(new Tuple<IDChainDefinition, IDChainDefinition>(complexIDNode, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(simpleValue, complexValue), new Tuple<AExpressionDefinition, AExpressionDefinition>(extraordinaryValue, null)); }
public abstract Exceptional<AOperationDefinition> SimpleOperation(AOperationDefinition left, AOperationDefinition right, TypesOfBinaryExpression typeOfBinExpr);
public override Exceptional<IExpressionGraph> TypeOperation(IExpressionGraph myLeftValueObject, IExpressionGraph myRightValueObject, DBContext dbContext, TypesOfBinaryExpression typeOfBinExpr, TypesOfAssociativity associativity, IExpressionGraph result, bool aggregateAllowed = true) { myLeftValueObject.UnionWith(myRightValueObject); return new Exceptional<IExpressionGraph>(myLeftValueObject); }
/// <summary> /// Extracts data for a binary expression /// </summary> /// <param name="myComplexValue">The complex part of the binary expression.</param> /// <param name="mySimpleValue">The simple/atomic part of the expression.</param> /// <param name="errors">The list of errors.</param> /// <param name="typeOfBinExpr">The kind of the binary expression</param> /// <returns>A data tuple.</returns> private Exceptional<DataContainer> ExtractData(AExpressionDefinition myComplexValue, AExpressionDefinition mySimpleValue, ref TypesOfBinaryExpression typeOfBinExpr, DBObjectCache myDBObjectCache, SessionSettings mySessionToken, DBContext dbContext, Boolean aggregateAllowed) { #region data //the complex IDNode (sth. like U.Age or Count(U.Friends)) IDChainDefinition complexIDNode = null; //the value that is on the opposite of the complex IDNode AExpressionDefinition simpleValue = null; //a complex IDNode may result in a complexValue (i.e. Count(U.Friends) --> 3) AExpressionDefinition complexValue = null; //reference to former myComplexValue AExpressionDefinition extraordinaryValue = null; #endregion #region extraction if (myComplexValue is IDChainDefinition) { #region IDNode #region Data complexIDNode = (IDChainDefinition)myComplexValue; var validateResult = complexIDNode.Validate(dbContext, false); if (validateResult.Failed()) { return new Exceptional<DataContainer>(validateResult); } if (complexIDNode.Any(id => id is ChainPartFuncDefinition)) { if (complexIDNode.Edges.IsNullOrEmpty()) { #region parameterless function var fcn = (complexIDNode.First(id => id is ChainPartFuncDefinition) as ChainPartFuncDefinition); // somes functions (aggregates) like SUM are not valid for where expressions, though they are not resolved if (fcn.Function == null) return new Exceptional<DataContainer>(new Error_FunctionDoesNotExist(fcn.FuncName)); Exceptional<FuncParameter> pResult = fcn.Function.ExecFunc(dbContext); if (pResult.Failed()) { return new Exceptional<DataContainer>(pResult); } //simpleValue = new AtomValue(fcn.Function.TypeOfResult, ((FuncParameter)pResult.Value).Value); //the new simple value extraced from the function simpleValue = new ValueDefinition(((FuncParameter)pResult.Value).Value); typeOfBinExpr = TypesOfBinaryExpression.Unknown; //we do not know if we are left or right associated complexIDNode = null; //we resolved it... so it's null #endregion } else { //extraordinaryValue = (complexIDNode.First(id => id is ChainPartFuncDefinition) as ChainPartFuncDefinition); extraordinaryValue = complexIDNode; if (mySimpleValue is ValueDefinition) { simpleValue = mySimpleValue; } } } else { if(mySimpleValue is ValueDefinition) { try { if (complexIDNode.IsUndefinedAttribute) { throw new GraphDBException(new Error_AttributeIsNotDefined(complexIDNode.UndefinedAttribute)); } simpleValue = GetCorrectValueDefinition(complexIDNode.LastAttribute, complexIDNode.LastType, ((ValueDefinition)mySimpleValue), dbContext, mySessionToken); } catch (FormatException) { return new Exceptional<DataContainer>(new Error_DataTypeDoesNotMatch(complexIDNode.LastAttribute.GetDBType(dbContext.DBTypeManager).Name, ((ValueDefinition)mySimpleValue).Value.ObjectName)); } } else { if (mySimpleValue is TupleDefinition) { ((TupleDefinition)mySimpleValue).ConvertToAttributeType(complexIDNode.LastAttribute, dbContext); simpleValue = mySimpleValue; } //else if (mySimpleValue is TupleNode) //{ // var simpleValE = (mySimpleValue as TupleNode).GetAsTupleValue(dbContext, complexIDNode.LastAttribute); // if (!simpleValE.Success()) // { // return new Exceptional<DataContainer>(simpleValE); // } // simpleValue = simpleValE.Value; //} else { //return new Exceptional<DataContainer>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } } } #endregion #endregion } else if (myComplexValue is TupleDefinition) { #region TupleSetNode complexValue = ((TupleDefinition)myComplexValue); simpleValue = mySimpleValue; typeOfBinExpr = TypesOfBinaryExpression.Atom; #endregion } else if (myComplexValue is AggregateDefinition) { #region AggregateNode if (aggregateAllowed) { if (((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters.Count != 1) { return new Exceptional<DataContainer>(new Error_ArgumentException("An aggregate must have exactly one expression.")); } if (!(((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters[0] is IDChainDefinition)) { return new Exceptional<DataContainer>(new Error_ArgumentException("An aggregate must have exactly one IDNode.")); } #region Data complexIDNode = (((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters[0] as IDChainDefinition); if (complexIDNode == null) { return new Exceptional<DataContainer>(new Error_InvalidIDNode("Only single IDNodes are currently allowed in aggregates!")); } #endregion #region values simpleValue = mySimpleValue; extraordinaryValue = myComplexValue; #endregion } else { return new Exceptional<DataContainer>(new Error_AggregateNotAllowed(((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition)); } #endregion } else { return new Exceptional<DataContainer>(new Error_NotImplementedExpressionNode(myComplexValue.GetType())); } #endregion return new Exceptional<DataContainer>(new DataContainer(new Tuple<IDChainDefinition, IDChainDefinition>(complexIDNode, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(simpleValue, complexValue), new Tuple<AExpressionDefinition, AExpressionDefinition>(extraordinaryValue, null))); }
public override IEnumerable<ObjectUUID> IndexOperation(AAttributeIndex myIndex, TupleDefinition myTuple, TypesOfBinaryExpression typeOfBinExpr, DBContext dbContext) { HashSet<ObjectUUID> interestingUUIDs = new HashSet<ObjectUUID>(); IndexKey idxLookupKey = null; var currentType = dbContext.DBTypeManager.GetTypeByUUID(myIndex.IndexRelatedTypeUUID); var myOperationValues = myTuple; switch (typeOfBinExpr) { case TypesOfBinaryExpression.LeftComplex: if (!myIndex.IsListOfBaseObjectsIndex) { foreach (var aItem in myOperationValues) { idxLookupKey = new IndexKey(myIndex.IndexKeyDefinition.IndexKeyAttributeUUIDs[0], (aItem.Value as ValueDefinition).Value, myIndex.IndexKeyDefinition); interestingUUIDs.UnionWith(myIndex.GetValues(idxLookupKey, currentType, dbContext)); } } else { #region In case the index is from a set or list of baseobjects we use this way to get the values foreach (var aItem in myOperationValues) { idxLookupKey = new IndexKey(myIndex.IndexKeyDefinition.IndexKeyAttributeUUIDs[0], (aItem.Value as ValueDefinition).Value, myIndex.IndexKeyDefinition); interestingUUIDs.UnionWith(myIndex.GetValues(idxLookupKey, currentType, dbContext)); } /* What the hack is that??? - This is too slow for any usual usage of in operator! */ var indexRelatedType = dbContext.DBTypeManager.GetTypeByUUID(myIndex.IndexRelatedTypeUUID); foreach (var aKey in myIndex.GetKeys(currentType, dbContext).Where(item => !myOperationValues.Contains(new TupleElement(new ValueDefinition(item.IndexKeyValues[0]))))) { foreach (var aMatch in myIndex.GetValues(aKey, indexRelatedType, dbContext).Intersect(interestingUUIDs)) { interestingUUIDs.Remove(aMatch); } } #endregion } break; case TypesOfBinaryExpression.RightComplex: var myEnumerator = myOperationValues.GetEnumerator(); if (myEnumerator.MoveNext()) { idxLookupKey = new IndexKey(myIndex.IndexKeyDefinition.IndexKeyAttributeUUIDs[0], (myEnumerator.Current.Value as ValueDefinition).Value, myIndex.IndexKeyDefinition); interestingUUIDs.UnionWith(myIndex.GetValues(idxLookupKey, currentType, dbContext)); while (myEnumerator.MoveNext()) { idxLookupKey = new IndexKey(myIndex.IndexKeyDefinition.IndexKeyAttributeUUIDs[0], (myEnumerator.Current.Value as ValueDefinition).Value, myIndex.IndexKeyDefinition); interestingUUIDs.IntersectWith(myIndex.GetValues(idxLookupKey, currentType, dbContext)); } } break; case TypesOfBinaryExpression.Atom: case TypesOfBinaryExpression.Complex: case TypesOfBinaryExpression.Unknown: default: break; } foreach (var aValidUUID in interestingUUIDs) { yield return aValidUUID; } yield break; }
protected Exceptional<AOperationDefinition> SimpleOperation(TupleDefinition left, TupleDefinition right, TypesOfBinaryExpression myTypeOfBinaryExpression) { Object resultValue = true; HashSet<ADBBaseObject> anotherValues = new HashSet<ADBBaseObject>(); switch (myTypeOfBinaryExpression) { case TypesOfBinaryExpression.LeftComplex: #region left complex //foreach (var aRightValue in right) //{ // anotherValues.Add(GraphDBTypeMapper.GetGraphObjectFromType(left.TypeOfOperatorResult, (aRightValue.Value as ValueDefinition).Value.Value)); //} foreach (var aLeft in left) { if (!right.Contains(aLeft)) { resultValue = false; break; } } #endregion break; case TypesOfBinaryExpression.RightComplex: #region right complex //foreach (var aLeftValue in left.TupleValue.GetAllValues()) //{ // anotherValues.Add(GraphDBTypeMapper.GetGraphObjectFromType(right.TupleValue.TypeOfValue, aLeftValue)); //} foreach (var aAnother in left) { if (!right.Contains(aAnother)) { resultValue = false; break; } } #endregion break; default: break; } return new Exceptional<AOperationDefinition>(new ValueDefinition(BasicType.Boolean, (object)resultValue)); }
protected Exceptional<AOperationDefinition> SimpleOperation(ValueDefinition left, TupleDefinition right, TypesOfBinaryExpression myTypeOfBinaryExpression) { #region Data ValueDefinition resultObject = null; Object resultValue = false; #endregion resultValue = right.Contains(new TupleElement(left)); resultObject = new ValueDefinition(BasicType.Boolean, (object)resultValue); return new Exceptional<AOperationDefinition>(resultObject); }
protected Exceptional<AOperationDefinition> SimpleOperation(ValueDefinition left, ValueDefinition right, TypesOfBinaryExpression myTypeOfBinaryExpression) { #region Data ValueDefinition resultObject = null; Object resultValue = false; #endregion resultValue = Compare(left.Value, right.Value); resultObject = new ValueDefinition(BasicType.Boolean, (object)resultValue); return new Exceptional<AOperationDefinition>(resultObject); }
public override Exceptional<AOperationDefinition> SimpleOperation(AOperationDefinition left, AOperationDefinition right, TypesOfBinaryExpression myTypeOfBinaryExpression) { if (left is ValueDefinition) { if (right is ValueDefinition) { return SimpleOperation((ValueDefinition)left, (ValueDefinition)right, myTypeOfBinaryExpression); } else { return SimpleOperation((ValueDefinition)left, (TupleDefinition)right, myTypeOfBinaryExpression); } } else { if (right is ValueDefinition) { return SimpleOperation((TupleDefinition)left, (ValueDefinition)right, myTypeOfBinaryExpression); } else { return SimpleOperation((TupleDefinition)left, (TupleDefinition)right, myTypeOfBinaryExpression); } } }
public virtual bool IsValidIndexOperation(DataContainer data, DBContext myTypeManager, TypesOfBinaryExpression typeOfBinExpr) { return true; }
private IEnumerable<ObjectUUID> IndexSingleOperation(AAttributeIndex myIndex, AOperationDefinition myOperationValue, AttributeUUID myAttributeUUID, TypesOfBinaryExpression typeOfBinExpr, DBContext dbContext) { if (myOperationValue is ValueDefinition) { return IndexSingleOperation(myIndex, ((ValueDefinition)myOperationValue).Value, myAttributeUUID, typeOfBinExpr, dbContext); } else { if (myOperationValue is TupleDefinition) { return IndexOperation(myIndex, (myOperationValue as TupleDefinition), typeOfBinExpr, dbContext); } else { throw new GraphDBException(new Error_NotImplemented(new System.Diagnostics.StackTrace(true), "Currently, it is not implemented to execute an IndexOperation on anything else but AtomValue or TupleValue.")); } } }
/// <summary> /// Finds matching result corresponding to a binary expression. /// </summary> /// <param name="myLeftValueObject">The left value of a binary expression.</param> /// <param name="myRightValueObject">The right value of a binary expression.</param> /// <returns></returns> public static IExpressionGraph TypeOperation( AExpressionDefinition myLeftValueObject, AExpressionDefinition myRightValueObject, GQLPluginManager myPluginManager, IGraphDB myGraphDB, SecurityToken mySecurityToken, Int64 myTransactionToken, TypesOfBinaryExpression typeOfBinExpr, IExpressionGraph resultGr, TypesOfOperators mytypesOfOpertators, BinaryOperator myOperator, Boolean aggregateAllowed = true) { #region Data //DataContainer for all data that is used by a binary expression/comparer DataContainer data; #endregion #region extract data //data extraction with an eye on the type of the binary expression switch (typeOfBinExpr) { case TypesOfBinaryExpression.Atom: //sth like 3 = 4 #region Get Atom data //no further data has to be generated //data = new DataContainer(null, new Tuple<Object, Object>(myLeftValueObject, myRightValueObject), null); data = new DataContainer(); #endregion break; case TypesOfBinaryExpression.LeftComplex: //sth like U.Age = 21 #region Get LeftComplex data data = ExtractData(myLeftValueObject, myRightValueObject, ref typeOfBinExpr, myPluginManager, myGraphDB, mySecurityToken, myTransactionToken, aggregateAllowed); #endregion break; case TypesOfBinaryExpression.RightComplex: //sth like 21 = U.Age #region Get RightComplex data data = ExtractData(myRightValueObject, myLeftValueObject, ref typeOfBinExpr, myPluginManager, myGraphDB, mySecurityToken, myTransactionToken, aggregateAllowed); #endregion break; case TypesOfBinaryExpression.Complex: //sth like U.Age = F.Alter #region Get Complex data var leftData = ExtractData(myLeftValueObject, myRightValueObject, ref typeOfBinExpr, myPluginManager, myGraphDB, mySecurityToken, myTransactionToken, aggregateAllowed); var rightData = ExtractData(myRightValueObject, myLeftValueObject, ref typeOfBinExpr, myPluginManager, myGraphDB, mySecurityToken, myTransactionToken, aggregateAllowed); if (typeOfBinExpr == TypesOfBinaryExpression.Unknown) { typeOfBinExpr = SetTypeOfBinaryExpression(leftData, rightData); switch (typeOfBinExpr) { case TypesOfBinaryExpression.Atom: data = new DataContainer(new Tuple<IDChainDefinition, IDChainDefinition>(null, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(leftData.Operands.Item1, leftData.Operands.Item1), new Tuple<AExpressionDefinition, AExpressionDefinition>(null, null)); break; case TypesOfBinaryExpression.LeftComplex: data = new DataContainer(new Tuple<IDChainDefinition, IDChainDefinition>(leftData.IDChainDefinitions.Item1, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(rightData.Operands.Item1, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(null, null)); break; case TypesOfBinaryExpression.RightComplex: data = new DataContainer(new Tuple<IDChainDefinition, IDChainDefinition>(rightData.IDChainDefinitions.Item1, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(leftData.Operands.Item1, null), new Tuple<AExpressionDefinition, AExpressionDefinition>(null, null)); break; case TypesOfBinaryExpression.Complex: case TypesOfBinaryExpression.Unknown: default: throw new NotImplementedQLException(""); } } else { data = JoinData(leftData, rightData); } #endregion break; default: throw new ArgumentException(); } #endregion #region match data switch (typeOfBinExpr) { case TypesOfBinaryExpression.Atom: #region Atom //do nothing 3 = 3 (or 2 != 3) doesnt bother U #endregion break; case TypesOfBinaryExpression.LeftComplex: #region LeftComplex MatchData(data, resultGr, myGraphDB, mySecurityToken, myTransactionToken, mytypesOfOpertators, myOperator); #endregion break; case TypesOfBinaryExpression.RightComplex: #region RightComplex MatchData(data, resultGr, myGraphDB, mySecurityToken, myTransactionToken, mytypesOfOpertators, myOperator); #endregion break; case TypesOfBinaryExpression.Complex: #region Complex throw new NotImplementedQLException(""); #endregion } #endregion return resultGr; }
private Exceptional<object> IntegrateUUID(DataContainer data, DBContext dbContext, DBObjectCache dbObjectCache, TypesOfBinaryExpression typeOfBinExpr, IExpressionGraph resultGraph, SessionSettings mySessionToken, LevelKey myLevelKey, IEnumerable<Exceptional<DBObjectStream>> myDBObjects) { foreach (var aDBO in myDBObjects) { if (aDBO.Failed()) { return new Exceptional<object>(aDBO); } if (IsValidDBObjectStreamForBinExpr(aDBO.Value, data.IDChainDefinitions.Item1.LastAttribute, dbContext.DBTypeManager)) { //check and integrate var result = CheckAndIntegrateDBObjectStream(data, dbContext, dbObjectCache, typeOfBinExpr, resultGraph, aDBO.Value, myLevelKey, mySessionToken); if(!result.Success()) { return new Exceptional<object>(result); } } } return new Exceptional<object>(); }
public abstract Exceptional<IExpressionGraph> TypeOperation(AExpressionDefinition myLeftValueObject, AExpressionDefinition myRightValueObject, DBContext dbContext, TypesOfBinaryExpression typeOfBinExpr, TypesOfAssociativity associativity, IExpressionGraph result, Boolean aggregateAllowed = true);
/// <param name="data">The DataContainer.</param> /// <param name="dbContext">The TypeManager of the database.</param> /// <param name="queryCache">The current query cache.</param> /// <param name="typeOfBinExpr">The type of the binary expression.</param> /// <param name="idx">The index for the complex part.</param> /// <param name="errors">A list of errors.</param> /// <param name="resultGraph">The IExpressionGraph that serves as result.</param> /// <returns>True if the method succeeded</returns> private Exceptional<Boolean> MatchData(DataContainer data, DBContext dbContext, DBObjectCache dbObjectCache, TypesOfBinaryExpression typeOfBinExpr, IEnumerable<Tuple<GraphDBType, AAttributeIndex>> idx, IExpressionGraph resultGraph, SessionSettings mySessionToken) { #region data LevelKey myLevelKey = CreateLevelKey(data.IDChainDefinitions.Item1, dbContext.DBTypeManager); #endregion foreach (var aIDX in idx) { //this is only for such type(DBVertex) that have no AAttributeIndex if (aIDX.Item2 == null) { continue; } #region Execution if (aIDX.Item2.IsUUIDIndex && (data.IDChainDefinitions.Item1.LastAttribute != dbContext.DBTypeManager.GetUUIDTypeAttribute())) { #region UUID idx - check ALL DBOs var IndexRelatedType = dbContext.DBTypeManager.GetTypeByUUID(aIDX.Item2.IndexRelatedTypeUUID); var idxKeyValues = (aIDX.Item2).GetAllValues(IndexRelatedType, dbContext); if (idxKeyValues.CountIs(0)) { continue; } var uuids = idxKeyValues.Aggregate((elem, aggrresult) => aggrresult.Union(elem)); var result = IntegrateUUID(data, dbContext, dbObjectCache, typeOfBinExpr, resultGraph, mySessionToken, myLevelKey, dbObjectCache.LoadListOfDBObjectStreams(aIDX.Item1, uuids)); if (result.Failed()) { return new Exceptional<bool>(result); } if (resultGraph.ContainsLevelKey(myLevelKey)) { #region clean lower levels if (Type == TypesOfOperators.AffectsLowerLevels) { CleanLowerLevel(myLevelKey, dbContext, dbObjectCache, resultGraph); } #endregion } else { resultGraph.AddEmptyLevel(myLevelKey); } #endregion } else { #region Get operationValue and type var operationValue = (AOperationDefinition)data.Operands.Item1; #endregion #region Attribute index if (aIDX.Item2.IndexKeyDefinition.IndexKeyAttributeUUIDs.Count > 1) { return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true), "Currently it is not implemented to use compound indices.")); } var interestingUUIDsByIdx = IndexSingleOperation(aIDX.Item2, operationValue, data.IDChainDefinitions.Item1.LastAttribute.UUID, typeOfBinExpr, dbContext); #region integrate in graph var runMT = DBConstants.RunMT; if (runMT) { Parallel.ForEach(dbObjectCache.LoadListOfDBObjectStreams(data.IDChainDefinitions.Item1.LastType, interestingUUIDsByIdx), aDBO => { IntegrateInGraph(aDBO.Value, resultGraph, myLevelKey, dbContext, dbObjectCache); } ); } else { foreach (var aDBO in dbObjectCache.LoadListOfDBObjectStreams(data.IDChainDefinitions.Item1.LastType, interestingUUIDsByIdx)) { IntegrateInGraph(aDBO.Value, resultGraph, myLevelKey, dbContext, dbObjectCache); } } #endregion if (resultGraph.ContainsLevelKey(myLevelKey)) { #region clean lower levels if (Type == TypesOfOperators.AffectsLowerLevels) { CleanLowerLevel(myLevelKey, dbContext, dbObjectCache, resultGraph); } #endregion } else { resultGraph.AddEmptyLevel(myLevelKey); } #endregion } #endregion } return new Exceptional<bool>(true); }
/// <summary> /// Extracts data for a binary expression /// </summary> /// <param name="myComplexValue">The complex part of the binary expression.</param> /// <param name="mySimpleValue">The simple/atomic part of the expression.</param> /// <param name="errors">The list of errors.</param> /// <param name="typeOfBinExpr">The kind of the binary expression</param> /// <returns>A data tuple.</returns> private static DataContainer ExtractData(AExpressionDefinition myComplexValue, AExpressionDefinition mySimpleValue, ref TypesOfBinaryExpression typeOfBinExpr, GQLPluginManager myPluginManager, IGraphDB myGraphDB, SecurityToken mySecurityToken, Int64 myTransactionToken, Boolean aggregateAllowed) { #region data //the complex IDNode (sth. like U.Age or Count(U.Friends)) IDChainDefinition complexIDNode = null; //the value that is on the opposite of the complex IDNode AExpressionDefinition simpleValue = null; //a complex IDNode may result in a complexValue (i.e. Count(U.Friends) --> 3) AExpressionDefinition complexValue = null; //reference to former myComplexValue AExpressionDefinition extraordinaryValue = null; #endregion #region extraction if (myComplexValue is IDChainDefinition) { #region IDNode #region Data complexIDNode = (IDChainDefinition)myComplexValue; complexIDNode.Validate(myPluginManager, myGraphDB, mySecurityToken, myTransactionToken, false); if (complexIDNode.Any(id => id is ChainPartFuncDefinition)) { if (complexIDNode.Edges == null || complexIDNode.Edges.Count == 0) { #region parameterless function var fcn = (complexIDNode.First(id => id is ChainPartFuncDefinition) as ChainPartFuncDefinition); // somes functions (aggregates) like SUM are not valid for where expressions, though they are not resolved if (fcn.Function == null) { throw new FunctionDoesNotExistException(fcn.FuncName); } FuncParameter pResult = fcn.Function.ExecFunc(null, null, null, myGraphDB, mySecurityToken, myTransactionToken); //simpleValue = new AtomValue(fcn.Function.TypeOfResult, ((FuncParameter)pResult.Value).Value); //the new simple value extraced from the function simpleValue = new ValueDefinition(((FuncParameter)pResult).Value); typeOfBinExpr = TypesOfBinaryExpression.Unknown; //we do not know if we are left or right associated complexIDNode = null; //we resolved it... so it's null #endregion } else { //extraordinaryValue = (complexIDNode.First(id => id is ChainPartFuncDefinition) as ChainPartFuncDefinition); extraordinaryValue = complexIDNode; if (mySimpleValue is ValueDefinition) { simpleValue = mySimpleValue; } } } else { if (mySimpleValue is ValueDefinition) { try { if (complexIDNode.IsUndefinedAttribute) { throw new VertexAttributeIsNotDefinedException(complexIDNode.UndefinedAttribute); } simpleValue = GetCorrectValueDefinition(complexIDNode.LastAttribute, complexIDNode.LastType, ((ValueDefinition)mySimpleValue)); } catch (FormatException) { throw new DataTypeDoesNotMatchException(((IPropertyDefinition)complexIDNode.LastAttribute).BaseType.Name, ((ValueDefinition)mySimpleValue).Value.GetType().Name); } } else { if (mySimpleValue is TupleDefinition) { ((TupleDefinition)mySimpleValue).ConvertToAttributeType(myPluginManager, complexIDNode.LastAttribute, myGraphDB, mySecurityToken, myTransactionToken); simpleValue = mySimpleValue; } } } #endregion #endregion } else if (myComplexValue is TupleDefinition) { #region TupleSetNode complexValue = ((TupleDefinition)myComplexValue); simpleValue = mySimpleValue; typeOfBinExpr = TypesOfBinaryExpression.Atom; #endregion } else if (myComplexValue is AggregateDefinition) { #region AggregateNode if (aggregateAllowed) { if (((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters.Count != 1) { throw new GQLAggregateArgumentException("An aggregate must have exactly one expression."); } if (!(((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters[0] is IDChainDefinition)) { throw new GQLAggregateArgumentException("An aggregate must have exactly one IDNode."); } #region Data complexIDNode = (((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Parameters[0] as IDChainDefinition); if (complexIDNode == null) { throw new InvalidIDNodeException("Only single IDNodes are currently allowed in aggregates!"); } #endregion #region values simpleValue = mySimpleValue; extraordinaryValue = myComplexValue; #endregion } else { throw new AggregateNotAllowedException(((AggregateDefinition)myComplexValue).ChainPartAggregateDefinition.Aggregate.PluginShortName); } #endregion } else { throw new NotImplementedQLException(""); } #endregion return(new DataContainer(new Tuple <IDChainDefinition, IDChainDefinition>(complexIDNode, null), new Tuple <AExpressionDefinition, AExpressionDefinition>(simpleValue, complexValue), new Tuple <AExpressionDefinition, AExpressionDefinition>(extraordinaryValue, null))); }
public virtual IEnumerable<ObjectUUID> IndexOperation(AAttributeIndex myIndex, TupleDefinition myOperationValues, TypesOfBinaryExpression typeOfBinExpr, DBContext dbContext) { throw new GraphDBException(new Error_InvalidIndexOperation(myIndex.IndexName)); }
private Exceptional<Boolean> MatchComplexData(TypesOfAssociativity associativity, DataContainer data, DBContext dbContext, DBObjectCache dbObjectCache, TypesOfBinaryExpression typeOfBinExpr, IEnumerable<Tuple<GraphDBType, AAttributeIndex>> leftIndices, IEnumerable<Tuple<GraphDBType, AAttributeIndex>> rightIndices, ref List<GraphDBError> errors, ref IExpressionGraph result, SessionSettings mySessionToken) { #region data Dictionary<DBObjectStream, AOperationDefinition> operandsLeft = null; Dictionary<DBObjectStream, AOperationDefinition> operandsRight = null; #endregion #region handle extraordinaries if (data.Extraordinaries.Item1 != null) { #region left extraordinary //there is something like a function or so operandsLeft = new Dictionary<DBObjectStream, AOperationDefinition>(); //we have to calculate the real operand. //TODO: try to use attribute idx instead of uuid idx foreach (var aLeftIDX in leftIndices) { AAttributeIndex currentLeftIdx = null; #region get UUID idx if (!(aLeftIDX.Item2.IsUUIDIndex)) { currentLeftIdx = aLeftIDX.Item1.GetUUIDIndex(dbContext); } else { currentLeftIdx = aLeftIDX.Item2; } #endregion var currentIndexRelatedType = dbContext.DBTypeManager.GetTypeByUUID(currentLeftIdx.IndexRelatedTypeUUID); foreach (var aObjectUUIDs_Left in currentLeftIdx.GetAllValues(currentIndexRelatedType, dbContext)) { foreach (var aObjectUUID_Left in aObjectUUIDs_Left) { var leftDBObject = dbObjectCache.LoadDBObjectStream(aLeftIDX.Item1, aObjectUUID_Left); if (leftDBObject.Failed()) { throw new NotImplementedException(); } if (IsValidDBObjectStreamForBinExpr(leftDBObject.Value, data.IDChainDefinitions.Item1.LastAttribute, dbContext.DBTypeManager)) { var oper = GetOperand(data.IDChainDefinitions.Item1, data.Extraordinaries.Item1, dbContext, leftDBObject.Value, dbObjectCache, mySessionToken); if (oper.Failed()) return new Exceptional<bool>(oper); if (oper != null) { operandsLeft.Add(leftDBObject.Value, oper.Value); } } } } } //from now on the binary expression is right complex, because there are atom values on the left typeOfBinExpr = TypesOfBinaryExpression.RightComplex; #endregion } if (data.Extraordinaries.Item2 != null) { #region right extraordinary //there is something like a function or so operandsRight = new Dictionary<DBObjectStream, AOperationDefinition>(); foreach (var aRightIDX in rightIndices) { AAttributeIndex currentRightIdx = null; #region get UUID idx //we have to calculate the real operand. //TODO: try to use attribute idx instead of uuid idx if (!(aRightIDX.Item2.IsUUIDIndex)) { currentRightIdx = aRightIDX.Item1.GetUUIDIndex(dbContext); } else { currentRightIdx = aRightIDX.Item2; } #endregion var currentIndexRelatedType = dbContext.DBTypeManager.GetTypeByUUID(currentRightIdx.IndexRelatedTypeUUID); foreach (var aObjectUUIDs_Right in currentRightIdx.GetAllValues(currentIndexRelatedType, dbContext)) { foreach (var aObjectUUID_Right in aObjectUUIDs_Right) { var rightDBObject = dbObjectCache.LoadDBObjectStream(aRightIDX.Item1, aObjectUUID_Right); if (rightDBObject.Failed()) { throw new NotImplementedException(); } if (IsValidDBObjectStreamForBinExpr(rightDBObject.Value, data.IDChainDefinitions.Item2.LastAttribute, dbContext.DBTypeManager)) { var oper = GetOperand(data.IDChainDefinitions.Item2, data.Extraordinaries.Item2, dbContext, rightDBObject.Value, dbObjectCache, mySessionToken); if (oper.Failed()) return new Exceptional<bool>(oper); if (oper != null) { operandsRight.Add(rightDBObject.Value, oper.Value); } } } } } if (typeOfBinExpr == TypesOfBinaryExpression.RightComplex) { typeOfBinExpr = TypesOfBinaryExpression.Atom; } #endregion } #endregion switch (typeOfBinExpr) { case TypesOfBinaryExpression.Atom: #region atom switch (associativity) { case TypesOfAssociativity.Unknown: case TypesOfAssociativity.Neutral: GetComplexAtom(dbContext, operandsLeft, operandsRight, data.IDChainDefinitions.Item1, dbObjectCache, ref result); GetComplexAtom(dbContext, operandsRight, operandsLeft, data.IDChainDefinitions.Item2, dbObjectCache, ref result); break; case TypesOfAssociativity.Left: GetComplexAtom(dbContext, operandsLeft, operandsRight, data.IDChainDefinitions.Item1, dbObjectCache, ref result); break; case TypesOfAssociativity.Right: GetComplexAtom(dbContext, operandsRight, operandsLeft, data.IDChainDefinitions.Item2, dbObjectCache, ref result); break; default: return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } #endregion break; case TypesOfBinaryExpression.LeftComplex: #region Left complex GetComplexMatch(leftIndices, operandsRight, dbObjectCache, data.IDChainDefinitions.Item1, data.IDChainDefinitions.Item2, dbContext, associativity, ref result, mySessionToken); #endregion break; case TypesOfBinaryExpression.RightComplex: #region Right complex GetComplexMatch(rightIndices, operandsLeft, dbObjectCache, data.IDChainDefinitions.Item2, data.IDChainDefinitions.Item1, dbContext, associativity, ref result, mySessionToken); #endregion break; case TypesOfBinaryExpression.Complex: #region Complex LevelKey leftLevelKey = CreateLevelKey(data.IDChainDefinitions.Item1, dbContext.DBTypeManager); LevelKey rightLevelKey = CreateLevelKey(data.IDChainDefinitions.Item2, dbContext.DBTypeManager); GraphDBType leftGraphDBType = data.IDChainDefinitions.Item1.LastType; GraphDBType rightGraphDBType = data.IDChainDefinitions.Item2.LastType; #region exception if (leftIndices.CountIsGreater(1) || rightIndices.CountIsGreater(1)) { return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } #endregion var leftIndexRelatedType = dbContext.DBTypeManager.GetTypeByUUID(leftIndices.First().Item2.IndexRelatedTypeUUID); var rightIndexRelatedType = dbContext.DBTypeManager.GetTypeByUUID(rightIndices.First().Item2.IndexRelatedTypeUUID); foreach (var ObjectUUIDs_left in leftIndices.First().Item2.GetAllValues(leftIndexRelatedType, dbContext)) { foreach (var aLeftUUID in ObjectUUIDs_left) { var leftDBObject = dbObjectCache.LoadDBObjectStream(leftIndices.First().Item1, aLeftUUID); if (leftDBObject.Failed()) { return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } if (IsValidDBObjectStreamForBinExpr(leftDBObject.Value, data.IDChainDefinitions.Item1.LastAttribute, dbContext.DBTypeManager)) { foreach (var ObjectUUIDs_right in rightIndices.First().Item2.GetAllValues(rightIndexRelatedType, dbContext)) { foreach (var aRightUUID in ObjectUUIDs_right) { var rightDBObject = dbObjectCache.LoadDBObjectStream(rightIndices.First().Item1, aRightUUID); if (rightDBObject.Failed()) { return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } if (IsValidDBObjectStreamForBinExpr(rightDBObject.Value, data.IDChainDefinitions.Item2.LastAttribute, dbContext.DBTypeManager)) { //everything is valid var leftType = GraphDBTypeMapper.ConvertGraph2CSharp(data.IDChainDefinitions.Item1.LastAttribute.GetDBType(dbContext.DBTypeManager).Name); var rightType = GraphDBTypeMapper.ConvertGraph2CSharp(data.IDChainDefinitions.Item2.LastAttribute.GetDBType(dbContext.DBTypeManager).Name); AOperationDefinition leftValue; AOperationDefinition rightValue; if (data.IDChainDefinitions.Item1.LastAttribute.KindOfType == KindsOfType.SetOfReferences || data.IDChainDefinitions.Item1.LastAttribute.KindOfType == KindsOfType.ListOfNoneReferences || data.IDChainDefinitions.Item1.LastAttribute.KindOfType == KindsOfType.SetOfNoneReferences) leftValue = new TupleDefinition(leftType, leftDBObject.Value.GetAttribute(data.IDChainDefinitions.Item1.LastAttribute.UUID), data.IDChainDefinitions.Item1.LastAttribute.GetDBType(dbContext.DBTypeManager)); else leftValue = new ValueDefinition(leftType, leftDBObject.Value.GetAttribute(data.IDChainDefinitions.Item1.LastAttribute.UUID, data.IDChainDefinitions.Item1.LastAttribute.GetRelatedType(dbContext.DBTypeManager), dbContext)); if (data.IDChainDefinitions.Item2.LastAttribute.KindOfType == KindsOfType.SetOfReferences || data.IDChainDefinitions.Item2.LastAttribute.KindOfType == KindsOfType.ListOfNoneReferences || data.IDChainDefinitions.Item2.LastAttribute.KindOfType == KindsOfType.SetOfNoneReferences) rightValue = new TupleDefinition(rightType, rightDBObject.Value.GetAttribute(data.IDChainDefinitions.Item2.LastAttribute.UUID), data.IDChainDefinitions.Item2.LastAttribute.GetDBType(dbContext.DBTypeManager)); else rightValue = new ValueDefinition(rightType, rightDBObject.Value.GetAttribute(data.IDChainDefinitions.Item2.LastAttribute.UUID, data.IDChainDefinitions.Item2.LastAttribute.GetRelatedType(dbContext.DBTypeManager), dbContext)); var tempSimpleOperationResult = this.SimpleOperation(leftValue, rightValue, typeOfBinExpr); if (tempSimpleOperationResult.Failed()) return new Exceptional<bool>(tempSimpleOperationResult); var tempOperatorResult = tempSimpleOperationResult.Value; if ((Boolean)(tempOperatorResult as ValueDefinition).Value.Value) { //found sth that is really true #region insert into graph switch (associativity) { case TypesOfAssociativity.Neutral: case TypesOfAssociativity.Left: IntegrateInGraph(leftDBObject.Value, result, leftLevelKey, dbContext, dbObjectCache); break; case TypesOfAssociativity.Right: IntegrateInGraph(rightDBObject.Value, result, rightLevelKey, dbContext, dbObjectCache); break; case TypesOfAssociativity.Unknown: if (Type == TypesOfOperators.AffectsLowerLevels) { result.AddNodesWithComplexRelation(leftDBObject, leftLevelKey, rightDBObject, rightLevelKey, dbObjectCache, 1); } else { result.AddNodesWithComplexRelation(leftDBObject, leftLevelKey, rightDBObject, rightLevelKey, dbObjectCache, 0); } break; default: return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } #endregion } } } } #region clean lower levels if (Type == TypesOfOperators.AffectsLowerLevels) { switch (associativity) { case TypesOfAssociativity.Neutral: case TypesOfAssociativity.Left: CleanLowerLevel(leftLevelKey, dbContext, dbObjectCache, result); break; case TypesOfAssociativity.Right: CleanLowerLevel(rightLevelKey, dbContext, dbObjectCache, result); break; case TypesOfAssociativity.Unknown: CleanLowerLevel(leftLevelKey, dbContext, dbObjectCache, result); CleanLowerLevel(rightLevelKey, dbContext, dbObjectCache, result); break; default: return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } } #endregion } } } #endregion break; default: return new Exceptional<bool>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); } return new Exceptional<bool>(true); }
public override Exceptional<AOperationDefinition> SimpleOperation(AOperationDefinition left, AOperationDefinition right, TypesOfBinaryExpression myTypeOfBinaryExpression) { if (left is ValueDefinition && right is ValueDefinition) return SimpleOperation((ValueDefinition)left, (ValueDefinition)right); else if (left is ValueDefinition && right is TupleDefinition) return SimpleOperation((ValueDefinition)left, (TupleDefinition)right); // [1,3,5] IN 5 <-- makes no sence //else if (left is TupleValue && right is AtomValue) // return SimpleOperation((TupleValue)left, (AtomValue)right); else if (left is TupleDefinition && right is TupleDefinition) return SimpleOperation((TupleDefinition)left, (TupleDefinition)right); return new Exceptional<AOperationDefinition>(new Error_NotImplemented(new System.Diagnostics.StackTrace(true))); }