Beispiel #1
0
        private static IRowCursor QueryAllMatches(SystemTransaction transaction, TableName tableName, SystemTable table,
            IList<string> columns, SqlObject val)
        {
            // Try and find an index on these columns
            SystemIndexSetDataSource indexSet = transaction.FindIndexOn(tableName, columns);

            // If index found
            if (indexSet != null)
                // Query the index and find all matches
                return indexSet.Select(SelectableRange.Is(val));

            // Otherwise no index, so scan the table for matches

            // Make an Expression for the operation;
            //  (column1, column2, ...columnn) = val
            Expression compExp;
            int sz = columns.Count;
            if (sz > 1) {
                FunctionExpression cfunExp = new FunctionExpression("composite_fetch");
                for (int i = 0; i < sz; ++i) {
                    Expression varRef = new FetchVariableExpression(new Variable(tableName, columns[i]));
                    cfunExp.Parameters.Add(varRef);
                }
                compExp = cfunExp;
            } else if (sz == 1) {
                compExp = new FetchVariableExpression(new Variable(tableName, columns[0]));
            } else {
                throw new ApplicationException("Invalid columns list size");
            }

            // Equality test
            FunctionExpression funExp = new FunctionExpression("@is_sql");
            funExp.Parameters.Add(compExp);
            funExp.Parameters.Add(new FetchStaticExpression(val));

            // Create a query processor and perform the scan operation
            QueryProcessor processor = new QueryProcessor(transaction);
            ITable result = processor.FilterByScan(table, funExp);
            // Return the row cursor
            return result.GetRowCursor();
        }
Beispiel #2
0
            public Expression OnAfterWalk(Expression expression)
            {
                if (expression is SelectExpression) {
                    SelectExpression selectExp = (SelectExpression)expression;

                    // Exiting select, we expand the select output list to a complete
                    // form.

                    int sz = selectExp.Output.Count;

                    // Create a list of all forward referencable variables in the join
                    // graph
                    List<FetchVariableExpression> varList = new List<FetchVariableExpression>();
                    optimizer.PopulateVariables(varList, selectExp.Join);

                    // The unique table name of this select
                    TableName uniqueTableName = selectExp.UniqueName;
                    if (uniqueTableName == null)
                        throw new SystemException("Select must have a unique name.");

                    List<Expression> newOutList = new List<Expression>();
                    for (int i = 0; i < sz; ++i) {
                        // The Expression
                        SelectOutput selectOut = selectExp.Output[i];

                        // Is this a glob type?
                        if (selectOut.Expression is FetchGlobExpression) {
                            // Get the glob string
                            string str = ((FetchGlobExpression)selectOut.Expression).GlobString;
                            // Search the referencable list for matches,
                            bool matchFound = false;
                            foreach(FetchVariableExpression varExp in varList) {
                                Variable v = varExp.Variable;
                                // Found a match, add it to the list
                                if (optimizer.GlobMatch(str, v)) {
                                    SqlType returnType = varExp.ReturnType;
                                    Expression globExp = new FetchVariableExpression(v);
                                    globExp = new AliasVariableNameExpression(globExp, v);
                                    globExp.ReturnType = returnType;
                                    newOutList.Add(globExp);
                                    matchFound = true;
                                }
                            }
                            // If we searched the whole referencable list and no matches,
                            // we report the error.  This doesn't apply to the general
                            // glob "*" which is valid for results with no columns.
                            if (!str.Equals("*") && !matchFound)
                                throw new SqlParseException("'" + str + "' does not match anything", selectOut.Expression);
                        } else {
                            // The makes sure all other types of output from a select are
                            // named variable references.

                            // If this is an alias, we need to make sure we qualify it with
                            // this table name
                            if (selectOut.Expression is AliasVariableNameExpression) {
                                // Rewrite this alias name with the new unique table id
                                Variable v = selectOut.Alias;
                                if (v.TableName != null)
                                    throw new SqlParseException("Incorrect alias format", selectOut.Expression);

                                v = new Variable(uniqueTableName, v.Name);
                                selectOut.Alias = v;
                            }
                                // If it's not a fetchvar operation, we need to assign a
                                // unique alias name for this value
                            else if (!(selectOut.Expression is FetchVariableExpression)) {
                                string label = (string)selectOut.Expression.GetArgument("label");
                                if (label == null)
                                    label = "nolabel";

                                selectOut = new SelectOutput(
                                    new AliasVariableNameExpression(selectOut.Expression, new Variable(uniqueTableName, "#" + newOutList.Count + "#" + label)),
                                         selectOut.Alias);
                            }
                                // If it's a regular fetch variable operation, we need to
                                // forward qualify it and label it.
                            else {
                                selectOut.Expression = QualifyExpression(selectOut.Expression, varList, true);
                                Variable var = ((FetchVariableExpression)selectOut.Expression).Variable;
                                SqlType returnType = selectOut.Expression.ReturnType;
                                selectOut.Expression = new AliasVariableNameExpression(selectOut.Expression, var);
                                selectOut.Expression.ReturnType = returnType;
                            }

                            // Add it to the new select output list
                            newOutList.Add(selectOut.Expression);
                        }
                    }
                    // new_out_list is now the new expanded select output list
                    sz = newOutList.Count;

                    selectExp.Output.Clear();

                    for (int i = 0; i < sz; ++i) {
                        selectExp.Output.Add(new SelectOutput(newOutList[i]));
                    }

                    // Set the qualified flag for each select statement,
                    selectExp.IsQualified = true;

                }
                return expression;
            }
Beispiel #3
0
        private void PopulateVariables(IList<FetchVariableExpression> varList, Expression joinGraph)
        {
            // Exit early if join graph is null
            if (joinGraph == null)
                return;

            if (joinGraph is JoinExpression) {
                // Search the left and right for matching terms
                JoinExpression joinExp = (JoinExpression)joinGraph;
                PopulateVariables(varList, joinExp.Left);
                PopulateVariables(varList, joinExp.Right);
            } else if (joinGraph is FetchTableExpression) {
                // This must be fully qualified
                TableName table_name = ((FetchTableExpression)joinGraph).TableName;
                PopulateVariables(varList, table_name);
            } else if (joinGraph is AliasTableNameExpression) {
                AliasTableNameExpression aliasExp = (AliasTableNameExpression)joinGraph;
                TableName alias_name = aliasExp.Alias;
                // We find any that match in the child,
                List<FetchVariableExpression> newList = new List<FetchVariableExpression>();
                PopulateVariables(newList, aliasExp.Child);
                // And rewrite them with this table name alias
                int sz = newList.Count;
                for (int i = 0; i < sz; ++i) {
                    FetchVariableExpression varExp = newList[i];
                    Variable v = varExp.Variable;
                    FetchVariableExpression newVarExp = (FetchVariableExpression) varExp.Clone();
                    newVarExp.Variable = new Variable(alias_name, v.Name);
                    newVarExp.ReturnType = varExp.ReturnType;
                    varList.Add(newVarExp);
                }
            } else if (joinGraph is SelectExpression) {
                // For nested selects, we resolve against the select output only
                SelectExpression selectExp = (SelectExpression)joinGraph;
                int sz = selectExp.Output.Count;
                for (int i = 0; i < sz; ++i) {
                    Expression op = selectExp.Output[i].Expression;
                    Variable v;
                    SqlType varType;
                    if (op is FetchVariableExpression) {
                        FetchVariableExpression varExp = (FetchVariableExpression)op;
                        v = varExp.Variable;
                        varType = varExp.ReturnType;
                    } else if (op is AliasVariableNameExpression) {
                        AliasVariableNameExpression aliasExp = (AliasVariableNameExpression)op;
                        v = aliasExp.Alias;
                        varType = aliasExp.ReturnType;
                    } else {
                        throw new ApplicationException("Unknown output object in SELECT");
                    }
                    if (v != null) {
                        FetchVariableExpression varExp = new FetchVariableExpression(v);
                        varExp.ReturnType = varType;
                        varList.Add(varExp);
                    }
                }
            }
        }
Beispiel #4
0
        public void PopulateVariables(IList<FetchVariableExpression> varList, TableName tableName)
        {
            ITable tsource = transaction.GetTable(tableName);
            int sz = tsource.Columns.Count;
            for (int i = 0; i < sz; ++i) {
                TableColumn column = tsource.Columns[i];
                string columnName = column.Name;

                // The variable name,
                FetchVariableExpression varExp = new FetchVariableExpression(new Variable(tableName, columnName));
                // The type,
                SqlType returnType = column.Type;
                varExp.ReturnType = returnType;
                varList.Add(varExp);
            }
        }