private SelectTable ToSelectTable(ExecutedTable table) { var select = new SelectTable(); select.Columns = table.Descriptor.Properties.Select(x => new Sdk.SelectColumn() { Name = x.Name, Type = x.Type == null ? "" : x.Type.Name.ToString().ToLower() }).ToArray(); var list = new List <SelectRow>(); foreach (var row in table.Rows) { var selectRow = new SelectRow(); selectRow.Values = row.Values.Select(x => x.Value).ToArray(); list.Add(selectRow); } select.Rows = list.ToArray(); return(select); }
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(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); }