示例#1
0
        public static Func <RowHolder, bool> EvalWhere(Sql.where where, MetadataColumn[] metadataColumns, InputStringNormalizer stringNormalizer)
        {
            // TODO: This is all functional programming and nice
            // but I really doubt the perf.
            // Recursion + higher order functions is probably super slow...

            Func <RowHolder, bool> returnFilterFunc = null;

            returnFilterFunc = (rowHolder) =>
            {
                if (where.IsAnd)
                {
                    Sql.where.And andStmt = (Sql.where.And) where;

                    Func <RowHolder, bool> leftOp  = EvalWhere(andStmt.Item1, metadataColumns, stringNormalizer);
                    Func <RowHolder, bool> rightOp = EvalWhere(andStmt.Item2, metadataColumns, stringNormalizer);

                    return(leftOp(rowHolder) && rightOp(rowHolder));
                }
                else if (where.IsOr)
                {
                    Sql.where.Or orStmt = (Sql.where.Or) where;

                    Func <RowHolder, bool> leftOp  = EvalWhere(orStmt.Item1, metadataColumns, stringNormalizer);
                    Func <RowHolder, bool> rightOp = EvalWhere(orStmt.Item2, metadataColumns, stringNormalizer);

                    return(leftOp(rowHolder) || rightOp(rowHolder));
                }
                else if (where.IsCond)
                {
                    Sql.where.Cond condStmt = (Sql.where.Cond) where;
                    Sql.value      leftOp   = stringNormalizer.ApplyReplacementTokens(condStmt.Item.Item1);
                    Sql.op         op       = condStmt.Item.Item2;
                    Sql.value      rightOp  = stringNormalizer.ApplyReplacementTokens(condStmt.Item.Item3);

                    IComparable leftOpComp, rightOpComp;

                    leftOpComp  = ValToIComp(leftOp, ref metadataColumns, ref rowHolder);
                    rightOpComp = ValToIComp(rightOp, ref metadataColumns, ref rowHolder);

                    if (op.IsEq)
                    {
                        return(leftOpComp.CompareTo(rightOpComp) == 0);
                    }
                    else if (op.IsGe)
                    {
                        return(leftOpComp.CompareTo(rightOpComp) >= 0);
                    }
                    else if (op.IsGt)
                    {
                        return(leftOpComp.CompareTo(rightOpComp) > 0);
                    }
                    else if (op.IsLe)
                    {
                        return(leftOpComp.CompareTo(rightOpComp) <= 0);
                    }
                    else if (op.IsLt)
                    {
                        return(leftOpComp.CompareTo(rightOpComp) < 0);
                    }
                }

                throw new InvalidProgramException("Invalid state.");
            };

            return(returnFilterFunc);
        }
示例#2
0
        public async Task <PhyOpTableInsert> ParseInsertStatement(Sql.insertStatement insertStatement, ITransaction tran, InputStringNormalizer stringNormalizer)
        {
            string tableName = insertStatement.Table;

            MetadataTablesManager tableManager = metadataManager.GetTableManager();
            MetadataTable         table        = await tableManager.GetByName(tableName, tran).ConfigureAwait(false);

            ColumnInfo[] columnInfosFromTable = table.Columns.Select(mt => mt.ColumnType).ToArray();

            RowHolder rowHolder = new RowHolder(columnInfosFromTable);

            int colNum = 0;

            foreach (var value in insertStatement.Values)
            {
                if (value.IsFloat)
                {
                    if (columnInfosFromTable[colNum].ColumnType == ColumnType.Double)
                    {
                        rowHolder.SetField <double>(colNum, ((Sql.value.Float)value).Item);
                    }
                    else
                    {
                        throw new InvalidColumnTypeException();
                    }
                }
                else if (value.IsInt)
                {
                    if (columnInfosFromTable[colNum].ColumnType == ColumnType.Int)
                    {
                        rowHolder.SetField <int>(colNum, ((Sql.value.Int)value).Item);
                    }
                    else if (columnInfosFromTable[colNum].ColumnType == ColumnType.Double)
                    {
                        // Int can be cast to double without data loss.
                        rowHolder.SetField <double>(colNum, (double)((Sql.value.Int)value).Item);
                    }
                    else
                    {
                        throw new InvalidColumnTypeException();
                    }
                }
                else if (value.IsString)
                {
                    if (columnInfosFromTable[colNum].ColumnType == ColumnType.String)
                    {
                        // TODO: For string heap (strings of variable length separate logic is needed.

                        string input = ((Sql.value.String)value).Item;
                        input = stringNormalizer.ApplyReplacementTokens(input);
                        rowHolder.SetField(colNum, input.ToCharArray());
                    }
                    else
                    {
                        throw new InvalidColumnTypeException();
                    }
                }
                else
                {
                    throw new ArgumentException();
                }

                colNum++;
            }

            PhyOpStaticRowProvider opStatic = new PhyOpStaticRowProvider(rowHolder);

            PhyOpTableInsert op = new PhyOpTableInsert(table.Collection, opStatic);

            return(op);
        }