void MulExpr(out OqlExpression expression) { OqlExpression child; OqlExpression result = new OqlExpression(la.line, la.col); string newOp = null; Unary(out child); result.Add(child); while (StartOf(4)) { if (la.kind == 33) { Get(); newOp = "*"; } else if (la.kind == 34) { Get(); newOp = "/"; } else if (la.kind == 35) { Get(); newOp = "%"; } else { Get(); newOp = "MOD"; } Unary(out child); result.Add(child, newOp); } expression = result.Simplify(); }
void AndExpr(out OqlExpression expression) { OqlExpression child; OqlExpression result = new OqlExpression(la.line, la.col); EqlExpr(out child); result.Add(child); while (la.kind == 5) { Get(); bool negated = false; if (la.kind == 7) { Get(); negated = true; } EqlExpr(out child); if (negated) { child.UnaryOp = "NOT"; } result.Add(child, "AND"); } expression = result.Simplify(); }
void AddExpr(out OqlExpression expression) { OqlExpression child; OqlExpression result = new OqlExpression(la.line, la.col); string newOp = null; MulExpr(out child); result.Add(child); while (la.kind == 31 || la.kind == 32) { if (la.kind == 31) { Get(); newOp = "+"; } else { Get(); newOp = "-"; } MulExpr(out child); result.Add(child, newOp); } expression = result.Simplify(); }
void StringList(out OqlExpression expression) { OqlExpression result = new OqlExpression(la.line, la.col); Expect(4); result.Add(new StringLiteralExpression(t.val, t.line, t.col)); while (la.kind == 37) { Get(); Expect(4); result.Add(new StringLiteralExpression(t.val, t.line, t.col), ","); } expression = result; }
void BitAndExpr(out OqlExpression expression) { OqlExpression child; OqlExpression result = new OqlExpression(la.line, la.col); AddExpr(out child); result.Add(child); while (la.kind == 30) { Get(); AddExpr(out child); result.Add(child, "&"); } expression = result.Simplify(); }
void BitOrExpr(out OqlExpression expression) { OqlExpression child; OqlExpression result = new OqlExpression(la.line, la.col); BitXorExpr(out child); result.Add(child); while (la.kind == 28) { Get(); BitXorExpr(out child); result.Add(child, "|"); } expression = result.Simplify(); }
void Unary(out OqlExpression expression) { OqlExpression child; OqlExpression result = new OqlExpression(la.line, la.col); string newOp = null; if (la.kind == 31 || la.kind == 32 || la.kind == 36) { if (la.kind == 31) { Get(); newOp = "+"; } else if (la.kind == 32) { Get(); newOp = "-"; } else { Get(); newOp = "~"; } } Primary(out child); result.Add(child); child.UnaryOp = newOp; expression = result.Simplify(); }
void Initialize(MappingNode mappingNode, IEnumerable <OidColumn> oidColumns, IEnumerable <ForeignKeyColumn> fkColumns, KeyValuePair <string, int>?typeCodeInfo) { IEnumerator <OidColumn> oidEnumerator = oidColumns.GetEnumerator(); oidEnumerator.MoveNext(); List <OqlExpression> compareExpressions = new List <OqlExpression>(); foreach (ForeignKeyColumn fkColumn in fkColumns) { OidColumn oidColumn = oidEnumerator.Current; compareExpressions.Add(new OnCompareExpression(mappingNode, oidColumn, fkColumn)); oidEnumerator.MoveNext(); } if (typeCodeInfo.HasValue) { compareExpressions.Add(new OnCompareExpression(mappingNode, typeCodeInfo.Value.Key, typeCodeInfo.Value.Value)); } if (compareExpressions.Count == 1) { Add(compareExpressions[0]); } else { OqlExpression andExpression = new OqlExpression(0, 0); int i = 0; foreach (var compareExpression in compareExpressions) { if (i++ == 0) { andExpression.Add(compareExpression); } else { andExpression.Add(compareExpression, "AND"); } } Add(andExpression); } }
void NumList(out OqlExpression expression) { OqlExpression result = new OqlExpression(la.line, la.col); if (la.kind == 2) { Get(); result.Add(new NumberExpression(double.Parse(t.val, CultureInfo.InvariantCulture), t.line, t.col)); } else if (la.kind == 3) { Get(); result.Add(new NumberExpression(int.Parse(t.val), t.line, t.col)); } else { SynErr(42); } while (la.kind == 37) { Get(); if (la.kind == 2) { Get(); result.Add(new NumberExpression(double.Parse(t.val, CultureInfo.InvariantCulture), t.line, t.col), ","); } else if (la.kind == 3) { Get(); result.Add(new NumberExpression(int.Parse(t.val), t.line, t.col), ","); } else { SynErr(43); } } expression = result; }
void RootExpr(out OqlExpression expression) { OqlExpression child; OqlExpression result = new OqlExpression(la.line, la.col); bool negated = false; if (la.kind == 7) { Get(); negated = true; } OrExpr(out child); if (negated) { result.UnaryOp = "NOT"; } result.Add(child); expression = result.Simplify(); }
private void AnnotateExpressionTree(OqlExpression expressionTree) { foreach (ParameterExpression parExp in expressionTree.GetAll(e => e is ParameterExpression).ToList()) { if (Guid.Empty.Equals(parExp.ParameterValue) || DateTime.MinValue.Equals(parExp.ParameterValue)) { var parent = parExp.Parent; if (parent.Operator == "=") { var i = parent.Children.IndexOf(parExp); var nullExp = new NamedConstantExpression("NULL", false, 0, 0); parent.Children[i] = nullExp; ((IManageExpression)nullExp).SetParent(parent); parent.Operator = "IS"; } if (parent.Operator == "<>") { var i = parent.Children.IndexOf(parExp); var nullExp = new NamedConstantExpression("NULL", true, 0, 0); parent.Children[i] = nullExp; ((IManageExpression)nullExp).SetParent(parent); parent.Operator = "IS"; } } } foreach (IdentifierExpression exp in expressionTree.GetAll(e => e is IdentifierExpression).ToList()) { string[] arr = ((string)exp.Value).Split('.'); string fieldName = arr[arr.Length - 1]; // In case of embedded or value types this will be overwritten Relation relation; Class parentClass = GetParentClass(exp, arr, out fieldName, out relation); if (fieldName == "oid") { string[] oidColumns = (from c in parentClass.Oid.OidColumns select QualifiedColumnName.Get(c)).ToArray(); if (relation != null) { // In these cases we don't need the join to the table of the class owning the oid. // It's sufficient to compare against the foreign keys stored in the owner class' table // or in the mapping table if (relation.MappingTable != null) { oidColumns = (from c in relation.MappingTable.ChildForeignKeyColumns select QualifiedColumnName.Get(relation.MappingTable, c)).ToArray(); } else if (relation.Multiplicity == RelationMultiplicity.Element) { oidColumns = (from c in relation.ForeignKeyColumns select QualifiedColumnName.Get(c)).ToArray(); } } ParameterExpression parExp = exp.Siblings[0] as ParameterExpression; var isDirectSingleExpression = exp.Parent.Operator != "=" || oidColumns.Length == 1 && exp.Siblings[0] is ConstantExpression; // like "oid = 123" if (parExp == null && !isDirectSingleExpression) { throw new QueryException(10010, $"Expression '{exp.ToString()}' resolves to an oid. It's sibling expression must be a ParameterExpression. But the sibling is {exp.Siblings[0]}"); } object[] oidKeys = null; if (!isDirectSingleExpression) { // split the ObjectId or an array into individual parameters oidKeys = ExtractOidKeys(parExp); // Now set the parameter value of the first column if (oidKeys != null) { parExp.ParameterValue = oidKeys[0]; } } if (oidColumns.Length > 1 && exp.Children.Count == 0) { OqlExpression equalsExpression = exp.Parent; // Must be a = expression like 'xxx.oid = {0}'. // We need some additional parameters for the additional columns. MoveParameterExpression(expressionTree, parExp.Ordinal, oidColumns.Length - 1); // Replace the parent expression with a new AND expression OqlExpression andExpression = new OqlExpression(0, 0); ((IManageExpression)andExpression).SetParent(equalsExpression.Parent); equalsExpression.Parent.Children.Remove(equalsExpression); equalsExpression.Parent.Add(andExpression); // We need to set Parent and Child explicitly. // See comment in IManageExpression.SetParent. // Reuse the original equality expression as first child of the AND expression ((IManageExpression)equalsExpression).SetParent(andExpression); andExpression.Add(equalsExpression); exp.SetAnnotation(anKey, oidColumns[0]); int currentOrdinal = parExp.Ordinal; // Now add the additional children of the AND expression for (int i = 1; i < oidColumns.Length; i++) { OqlExpression newParent = equalsExpression.DeepClone; // equality expression and it's both children andExpression.Add(newParent, "AND"); ((IManageExpression)newParent).SetParent(andExpression); // Now patch the Annotation and a new parameter to the children IdentifierExpression newIdentExp = (IdentifierExpression)newParent.Children.Where(e => e is IdentifierExpression).First(); newIdentExp.SetAnnotation(anKey, oidColumns[i]); ParameterExpression newParExp = (ParameterExpression)newParent.Children.Where(e => e is ParameterExpression).First(); if (oidKeys != null) { newParExp.ParameterValue = oidKeys[i]; } newParExp.Ordinal = ++currentOrdinal; } } else { int index = 0; if (exp.Children.Count > 0 && exp.Children[0] is IndexExpression) { index = (int)exp.Children[0].Value; } if (index >= oidColumns.Length) { throw new IndexOutOfRangeException("oid index exceeds oid column count"); } exp.SetAnnotation(anKey, oidColumns[index]); } } else { Field field = parentClass.FindField(fieldName); if (field != null) { exp.SetAnnotation(anKey, QualifiedColumnName.Get(field.Column)); } else { Relation oneTooneRelation = parentClass.Relations.FirstOrDefault(r => r.Multiplicity == RelationMultiplicity.Element && (r.FieldName == fieldName || r.AccessorName == fieldName)); if (oneTooneRelation != null) { exp.SetAnnotation(anKey, QualifiedColumnName.Get(oneTooneRelation.ForeignKeyColumns.First())); } else { throw new Exception("Can't find Field mapping for " + fieldName + " in " + exp.Value); } } } } }
void RelExpr(out OqlExpression expression) { OqlExpression child; OqlExpression result = new OqlExpression(la.line, la.col); string newOp = null; bool negated = false; BitOrExpr(out child); result.Add(child); if (StartOf(2)) { if (StartOf(3)) { switch (la.kind) { case 22: { Get(); newOp = "<"; break; } case 23: { Get(); newOp = ">"; break; } case 24: { Get(); newOp = "<="; break; } case 25: { Get(); newOp = ">="; break; } case 26: { Get(); newOp = ">="; break; } case 27: { Get(); newOp = "<="; break; } } BitOrExpr(out child); result.Add(child, newOp); } else if (la.kind == 11) { Get(); if (la.kind == 7) { Get(); negated = true; } Expect(12); result.Add(new NamedConstantExpression("NULL", negated, t.line, t.col), "IS"); } else { if (la.kind == 7) { Get(); negated = true; } Expect(10); BitOrExpr(out child); result.Add(child, "BETWEEN"); Expect(5); BitOrExpr(out child); result.Add(child, "BETWEEN"); } } expression = result.Simplify(); }
void EqlExpr(out OqlExpression expression) { OqlExpression child; OqlExpression result = new OqlExpression(la.line, la.col); string newOp = null; bool negated = false; if (!(scanner.Peek().kind == _IN)) { RelExpr(out child); result.Add(child); while (StartOf(1)) { if (la.kind == 17) { Get(); newOp = "<>"; } else if (la.kind == 18) { Get(); newOp = "<>"; } else if (la.kind == 19) { Get(); newOp = "="; if (la.kind == 7) { Get(); negated = true; } } else { Get(); newOp = "LIKE"; } RelExpr(out child); if (negated) { child.UnaryOp = "NOT"; } result.Add(child, newOp); } } else if (la.kind == 1) { Identifier(out child); result.Add(child); Expect(15); Expect(20); if (la.kind == 2 || la.kind == 3) { NumList(out child); child.HasBrackets = true; result.Add(child, "IN"); } else if (la.kind == 4) { StringList(out child); child.HasBrackets = true; result.Add(child, "IN"); } else { SynErr(40); } Expect(21); } else { SynErr(41); } expression = result.Simplify(); }