public async Task <RowProvider> BuildTree(Sql.DmlDdlSqlStatement statement, ITransaction tran, InputStringNormalizer _) { if (!statement.IsCreate) { throw new ArgumentException(); } Sql.DmlDdlSqlStatement.Create createStatement = (Sql.DmlDdlSqlStatement.Create)statement; string tableName = createStatement.Item.Table; var columns = createStatement.Item.ColumnList.ToList(); MetadataTablesManager tableManager = this.metadataManager.GetTableManager(); TableCreateDefinition tableCreateDefinition = new TableCreateDefinition(); tableCreateDefinition.TableName = tableName; tableCreateDefinition.ColumnNames = columns.Select(c => c.Item3).ToArray(); tableCreateDefinition.ColumnTypes = columns.Select(c => { if (c.Item1.IsDoubleCType) { return(new ColumnInfo(ColumnType.Double)); } else if (c.Item1.IsIntCType) { return(new ColumnInfo(ColumnType.Int)); } else if (c.Item1.IsStringCType) { if (c.Item2 > MAX_STRING_LENGTH) { throw new ArgumentException("String too big."); } return(new ColumnInfo(ColumnType.String, c.Item2)); } else { throw new ArgumentException(); } }).ToArray(); await tableManager.CreateObject(tableCreateDefinition, tran).ConfigureAwait(false); return(new RowProvider(TaskExtension.EmptyEnumerable <RowHolder>(), new MetadataColumn[0])); }
public async Task <IPhysicalOperator <RowHolder> > BuildStatement(Sql.sqlStatement statement, ITransaction tran, IPhysicalOperator <RowHolder> source, InputStringNormalizer stringNormalizer) { if (source != null) { // For now source for scan must be null. // with subquery expression this will change. throw new ArgumentException(); } string tableName = statement.Table; MetadataTablesManager tableManager = metadataManager.GetTableManager(); MetadataTable table = await tableManager.GetByName(tableName, tran).ConfigureAwait(false); // Since we currently don't support indexes we can only build scan operation. return(new PhyOpScan(table.Collection, tran, table.Columns, table.TableName)); }
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); }