private static void addEvaluatedSelectItems(List <SelectItem> result, FilterItem item) { FilterItem[] orItems = item.getChildItems(); if (orItems != null) { foreach (FilterItem filterItem in orItems) { addEvaluatedSelectItems(result, filterItem); } } SelectItem selectItem = item.getSelectItem(); if (selectItem != null && !result.Contains(selectItem)) { result.Add(selectItem); } Object operand = item.getOperand(); if (operand != null && operand is SelectItem && !result.Contains((SelectItem)operand)) { result.Add((SelectItem)operand); } } // addEvaluatedSelectItems()
private FilterItem copyFilterItem(FilterItem item, Object[] values, NAtomicInteger parameterIndex) { if (item.isCompoundFilter()) { FilterItem[] childItems = item.getChildItems(); FilterItem[] newChildItems = new FilterItem[childItems.Length]; for (int i = 0; i < childItems.Length; i++) { FilterItem childItem = childItems[i]; FilterItem newChildItem = copyFilterItem(childItem, values, parameterIndex); newChildItems[i] = newChildItem; } NList <FilterItem> elements = new NList <FilterItem>(); foreach (FilterItem element in newChildItems) { elements.Add(element); } FilterItem newFilter = new FilterItem(item.getLogicalOperator(), elements); return(newFilter); } else { if (item.getOperand() is QueryParameter) { Object newOperand = values[parameterIndex.getAndIncrement()]; FilterItem newFilter = new FilterItem(item.getSelectItem(), item.getOperator(), newOperand); return(newFilter); } else { return(item); } } } // copyFilterItem()
private static bool selectFilterItems(HashSet <SelectItem> items, FilterItem fi) { IList <SelectItem> fiSelectItems = new List <SelectItem>(); fiSelectItems.Add(fi.getSelectItem()); Object operand = fi.getOperand(); if (operand is SelectItem) { fiSelectItems.Add((SelectItem)operand); } return(items.ContainsAll(fiSelectItems)); } // selectFilterItems()
} // constructor public DataSet executeQuery(Query query) { List <SelectItem> selectItems = query.getSelectClause().getItems(); List <FromItem> fromItems = query.getFromClause().getItems(); List <FilterItem> whereItems = query.getWhereClause().getItems(); List <SelectItem> whereSelectItems = query.getWhereClause().getEvaluatedSelectItems(); List <GroupByItem> groupByItems = query.getGroupByClause().getItems(); List <SelectItem> groupBySelectItems = query.getGroupByClause().getEvaluatedSelectItems(); List <SelectItem> havingSelectItems = query.getHavingClause().getEvaluatedSelectItems(); List <SelectItem> orderBySelectItems = query.getOrderByClause().getEvaluatedSelectItems(); List <FilterItem> havingItems = query.getHavingClause().getItems(); List <OrderByItem> orderByItems = query.getOrderByClause().getItems(); int firstRow = (query.getFirstRow() == null ? 1 : query.getFirstRow()); int maxRows = (query.getMaxRows() == null ? -1 : query.getMaxRows()); if (maxRows == 0) { // no rows requested - no reason to do anything return(new EmptyDataSet(selectItems)); } // check certain common query types that can often be optimized by // subclasses bool singleFromItem = fromItems.Count == 1; bool noGrouping = groupByItems.IsEmpty() && havingItems.IsEmpty(); if (singleFromItem && noGrouping) { FromItem fromItem = query.getFromClause().getItem(0); Table table = fromItem.getTable(); if (table != null) { // check for SELECT COUNT(*) queries if (selectItems.Count == 1) { SelectItem selectItem = query.getSelectClause().getItem(0); if (SelectItem.isCountAllItem(selectItem)) { bool functionApproximationAllowed = selectItem.isFunctionApproximationAllowed(); if (isMainSchemaTable(table)) { logger.debug("Query is a COUNT query with {} where items. Trying executeCountQuery(...)", whereItems.Count); NNumber count = executeCountQuery(table, whereItems, functionApproximationAllowed); if (count == null) { logger.debug( "DataContext did not return any count query results. Proceeding with manual counting."); } else { List <Row> data = new List <Row>(1); DataSetHeader header = new SimpleDataSetHeader(new SelectItem[] { selectItem }); data.Add(new DefaultRow(header, new Object[] { count })); return(new InMemoryDataSet(header, data)); } } } } bool is_simple_select = isSimpleSelect(query.getSelectClause()); if (is_simple_select) { // check for lookup query by primary key if (whereItems.Count == 1) { FilterItem whereItem = whereItems[0]; SelectItem selectItem = whereItem.getSelectItem(); if (!whereItem.isCompoundFilter() && selectItem != null && selectItem.getColumn() != null) { Column column = selectItem.getColumn(); if (column.isPrimaryKey() && OperatorType.EQUALS_TO.Equals(whereItem.getOperator())) { logger.debug( "Query is a primary key lookup query. Trying executePrimaryKeyLookupQuery(...)"); if (table != null) { if (isMainSchemaTable(table)) { Object operand = whereItem.getOperand(); Row row = executePrimaryKeyLookupQuery(table, selectItems, column, operand); if (row == null) { logger.debug( "DataContext did not return any GET query results. Proceeding with manual lookup."); } else { DataSetHeader header = new SimpleDataSetHeader(selectItems); return(new InMemoryDataSet(header, row)); } } } } } } // check for simple queries with or without simple criteria if (orderByItems.IsEmpty()) { DataSet ds = null; // no WHERE criteria set if (whereItems.IsEmpty()) { ds = materializeTable(table, selectItems, firstRow, maxRows); return(ds); } ds = materializeTable(table, selectItems, whereItems, firstRow, maxRows); return(ds); } } } } // Creates a list for all select items that are needed to execute query // (some may only be used as part of a filter, but not shown in result) List <SelectItem> workSelectItems = CollectionUtils.concat(true, selectItems, whereSelectItems, groupBySelectItems, havingSelectItems, orderBySelectItems); // Materialize the tables in the from clause DataSet[] fromDataSets = new DataSet[fromItems.Count]; for (int i = 0; i < fromDataSets.Length; i++) { FromItem fromItem = fromItems[i]; fromDataSets[i] = materializeFromItem(fromItem, workSelectItems); } // Execute the query using the raw data DataSet dataSet = null; // MetaModelHelper.getCarthesianProduct(fromDataSets, whereItems); // we can now exclude the select items imposed by the WHERE clause (and // should, to make the aggregation process faster) workSelectItems = CollectionUtils.concat(true, selectItems, groupBySelectItems, havingSelectItems, orderBySelectItems); if (groupByItems.Count > 0) { dataSet = MetaModelHelper.getGrouped(workSelectItems, dataSet, groupByItems); } else { dataSet = MetaModelHelper.getAggregated(workSelectItems, dataSet); } dataSet = MetaModelHelper.getFiltered(dataSet, havingItems); if (query.getSelectClause().isDistinct()) { dataSet = MetaModelHelper.getSelection(selectItems, dataSet); dataSet = MetaModelHelper.getDistinct(dataSet); dataSet = MetaModelHelper.getOrdered(dataSet, orderByItems); } else { dataSet = MetaModelHelper.getOrdered(dataSet, orderByItems); dataSet = MetaModelHelper.getSelection(selectItems, dataSet); } dataSet = MetaModelHelper.getPaged(dataSet, firstRow, maxRows); return(dataSet); } // executeQuery()