public void Visit(CaseStatement statement) { object value = null; foreach (var when in statement.WhenExpression) { var arg = new QueryPhaseArgs(); VisitChild(when.BooleanExpression, arg); if (arg.RowResult) //we matched { arg = new QueryPhaseArgs(); arg.BoolQueryArg = new Http.QueryArgs(); VisitChild(when.Variable, arg); //want to get it's value value = arg.BoolQueryArg.PropertyValue.Value; break; } } if (value == null && statement.ElseVariable != null) { var arg = new QueryPhaseArgs(); arg.BoolQueryArg = new Http.QueryArgs(); VisitChild(statement.ElseVariable, arg); //want to get it's value value = arg.BoolQueryArg.PropertyValue.Value; } _visitStack.Peek().BoolQueryArg.PropertyValue = new PropertyValue(value); }
private QueryPhaseArgs VisitChild(Element node, QueryPhaseArgs arg) { if (node != null) { _visitStack.Push(arg); node.Accept(this); return(_visitStack.Pop()); } return(null); }
public void Visit(NestedFromStatement statement) { var args = new QueryPhaseArgs(); VisitChild(statement.Query, args); if (args.QueryTable != null && statement.Alias != null) { _scope.AddTable(statement.Alias, args.QueryTable); } VisitChild(statement.InnerJoin); }
public void Visit(OrExpression expression) { var parentArgs = _visitStack.Peek() as QueryPhaseArgs; var leftArts = new QueryPhaseArgs(); VisitChild(expression.Left, leftArts); var rightArgs = new QueryPhaseArgs(); VisitChild(expression.Right, rightArgs); parentArgs.RowResult = leftArts.RowResult || rightArgs.RowResult; }
public void Visit(SubtractExpression expression) { var leftArg = new QueryPhaseArgs() { BoolQueryArg = new QueryArgs() }; VisitChild(expression.Left, leftArg); var rightArg = new QueryPhaseArgs() { BoolQueryArg = new QueryArgs() }; VisitChild(expression.Right, rightArg); _visitStack.Peek().BoolQueryArg.PropertyValue = ValidateTypes(leftArg.BoolQueryArg, rightArg.BoolQueryArg, (l, r) => l - r); }
public void Visit(GreaterThanExpression expression) { var leftArg = new QueryPhaseArgs() { BoolQueryArg = new QueryGreaterThan() }; VisitChild(expression.Left, leftArg); var rightArg = new QueryPhaseArgs() { BoolQueryArg = new QueryGreaterThan() }; VisitChild(expression.Right, rightArg); var parentArgs = _visitStack.Peek(); parentArgs.RowResult = ValidateTypes(leftArg.BoolQueryArg, rightArg.BoolQueryArg, (l, r) => l > r); }
public void Visit(SelectStatement statement) { var executedTables = _scope.FetchAllExecutedTablesSameLevel(); if (executedTables.Length == 0) //no executed tables. nothing to do { return; } var dynamicColumns = new List <DynamicColumn>(); var descriptors = new List <IResult>(); if (statement.All) //get all columns { var selectedIndex = 0; foreach (var executeTable in executedTables) { foreach (var p in executeTable.Descriptor.Properties) { int propIndex = executeTable.Descriptor.GetDataRowIndex(p.Name); descriptors.Add(new SelectColumn() { Table = executeTable, PropDescriptor = p, PropIndex = propIndex }); if (selectedIndex >= statement.Args.Length) { var selectArg = new SelectArgExpression(statement.Bounds); selectArg.Children.Add(new SingleVariableExpression(statement.Bounds) { Id = p.Name }); statement.Children.Add(selectArg); } selectedIndex++; } } } else { for (int selectIndex = 0; selectIndex < statement.Args.Length; selectIndex++) { Array.ForEach(executedTables, (x) => x.SelectIndex = selectIndex); var arg = new QueryPhaseArgs(); VisitChild(statement.Args[selectIndex], arg); if (arg.BoolQueryArg.Table == null) //can't find selected PropertyDescriptor. Must be a statement { var prop = new PropertyDescriptor() { Name = arg.BoolQueryArg.Variable ?? "(No column name)" }; var dynamicColumn = new DynamicColumn { SelectArgExpression = statement.Args[selectIndex], PropDescriptor = prop }; descriptors.Add(dynamicColumn); dynamicColumns.Add(dynamicColumn); } else { int propIndex = arg.BoolQueryArg.Table.Descriptor.GetDataRowIndex(arg.BoolQueryArg.Property.Name); arg.BoolQueryArg.Property.Name = arg.BoolQueryArg.Variable; descriptors.Add(new SelectColumn() { Table = arg.BoolQueryArg.Table, PropDescriptor = arg.BoolQueryArg.Property, PropIndex = propIndex }); } } } //need to go through every row here of select dynamic statement then add it Properties if (executedTables.Length > 0) { var rowCount = executedTables.First().Rows.Length; for (int row = 0; row < rowCount; row++) { Array.ForEach(executedTables, (x) => x.RowIndex = row); foreach (var d in dynamicColumns) //run each column. Value goes in data at selected index { var arg = new QueryPhaseArgs(); VisitChild(d.SelectArgExpression, arg); d.Values.Add(arg.BoolQueryArg.PropertyValue); } } } var rows = new List <Row>(); if (executedTables.Length > 0) { var rowCount = executedTables.First().Rows.Length; for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) //select data for only those columns selected { var values = new List <PropertyValue>(); for (int selectIndex = 0; selectIndex < statement.Args.Length; selectIndex++) { var selectedColumn = descriptors[selectIndex]; values.Add(selectedColumn.Fetch(rowIndex)); } rows.Add(new Row() { Values = values.ToArray() }); } } var finalDescriptors = descriptors.Select(x => x.Descriptor()).ToArray(); TableDescriptor tableDescriptor; //if nested if (statement.IsNestedQuery) { var dups = finalDescriptors.GroupBy(x => x.Name).Where(g => g.Count() > 1).Select(x => x.Key).ToList(); if (dups.Count > 1) //error { } tableDescriptor = finalDescriptors; } else { FinalSelectTableDescriptor ftableDescriptor = descriptors.Select(x => x.Descriptor()).ToArray(); tableDescriptor = ftableDescriptor; } var selectTable = new ExecutedTable(tableDescriptor) { Rows = rows.ToArray() }; _visitStack.Peek().QueryTable = selectTable; if (!statement.IsNestedQuery) { _selectResult.Add(ToSelectTable(selectTable)); } }
public void Visit(QueryStatement statement) { using (var s = _scope.Push()) { //Visit from to get tables in scope if (statement.From != null) { VisitChild(statement.From); } var executedTables = _scope.FetchAllExecutedTablesSameLevel(); if (executedTables.Length > 0 && statement.Where != null) { var rowCount = executedTables.First().Rows.Length; if (rowCount == 0) //even if no rows we still want to validate where variables { Array.ForEach(executedTables, (x) => x.RowIndex = 0); var arg = new QueryPhaseArgs(); VisitChild(statement.Where, arg); } else { for (int row = 0; row < rowCount; row++) { Array.ForEach(executedTables, (x) => x.RowIndex = row); var arg = new QueryPhaseArgs(); VisitChild(statement.Where, arg); if (!arg.RowResult) { Array.ForEach(executedTables, (x) => x.Rows[x.RowIndex].Match = false); } } } //remove rows that didn't match through all executed tables executedTables = _scope.FetchAllExecutedTablesSameLevel(); Array.ForEach(executedTables, (e) => { var joinedRows = new List <Row>(); Array.ForEach(e.Rows, r => { if (r.Match) { joinedRows.Add(r); } }); e.Rows = joinedRows.ToArray(); }); } if (statement.Limit != null) { VisitChild(statement.Limit); } var args = new QueryPhaseArgs(); if (statement.Select != null) { VisitChild(statement.Select, args); } _visitStack.Peek().QueryTable = args.QueryTable; if (statement.Bounds.Contains(_editorCursor) && ScopeModel == null) { ScopeModel = _scope.BuildScopeModel(); } } }
public void Visit(InnerJoinStatement statement) { string tableName = statement.Name; string tableVariable; if (statement.Alias != null) { tableVariable = statement.Alias; } else { tableVariable = statement.Name; } if (_scope.IsTableDefineSameLevel(tableName)) //table exists already { Errors.Add(new TableConflict(tableName, statement.Bounds.Start)); } if (!_scope.IsTableDefinedAnyLevel(tableName)) //we don't know this table at any level { Errors.Add(new TableNotDefined(tableName, statement.Bounds.Start)); return; } if (_scope.IsTableDefineSameLevel(tableVariable)) //if alias variable exists we have conflict { throw new InvalidOperationException(""); } var executedTables = _scope.FetchAllExecutedTablesSameLevel(); int rowCount = 0; if (executedTables.Length > 0) { rowCount = executedTables.First().Rows.Length; } var rightTableRows = new List <Row>(); if (rowCount == 0) //need to visit for semantic errors { var table = _scope.TableLookupAnyLevel(tableName); table = table.Create(); _scope.AddTable(tableVariable, table); VisitChild(statement.BooleanExpression); VisitWhereIgnoreErrors(statement.ParentQueryStatement.Where); var executeTable = table.Execute(statement.ParentQueryStatement.Limit); foreach (var e in table.Errors) { Errors.Add(e); } _scope.RemoveTable(tableVariable); } else { for (int row = 0; row < rowCount; row++) { var table = _scope.TableLookupAnyLevel(tableName); table = table.Create(); _scope.AddTable(tableVariable, table); Array.ForEach(executedTables, (x) => x.RowIndex = row); VisitChild(statement.BooleanExpression); VisitWhereIgnoreErrors(statement.ParentQueryStatement.Where); var executeTable = table.Execute(statement.ParentQueryStatement.Limit); foreach (var e in table.Errors) { Errors.Add(e); } _scope.RemoveTable(tableVariable); //remove query table _scope.AddTable(tableVariable, executeTable); // add execute table var arg = new QueryPhaseArgs(); VisitChild(statement.BooleanExpression, arg); if (arg.RowResult) //row passed join. If didn't row needs to be removed from the left joining result { Array.ForEach(executedTables, (x) => x.Rows[x.RowIndex].Expand = executeTable.Rows.Length); rightTableRows.AddRange(executeTable.Rows); } else //flag row as unmatching for all executed tables { Array.ForEach(executedTables, (x) => x.Rows[x.RowIndex].Match = false); } _scope.RemoveTable(tableVariable); } } var returnTable = _scope.TableLookupAnyLevel(tableName); var returnExecuteTable = new ExecutedTable(returnTable.Create().Descriptor) { Rows = rightTableRows.ToArray() }; _scope.AddTable(tableVariable, returnExecuteTable); executedTables = _scope.FetchAllExecutedTablesSameLevel(); Array.ForEach(executedTables, (e) => { var joinedRows = new List <Row>(); //Add matched rows Array.ForEach(e.Rows, r => { if (r.Match) { for (int x = 0; x < r.Expand; x++) { joinedRows.Add(r); } } }); e.Rows = joinedRows.ToArray(); }); VisitChild(statement.InnerJoin); }