DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
SelectIntoStatement.cs
Go to the documentation of this file.
1 //
2 // Copyright 2010-2015 Deveel
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 using System;
18 using System.IO;
19 
22 using Deveel.Data.Sql.Query;
23 using Deveel.Data.Sql.Tables;
24 
25 namespace Deveel.Data.Sql.Statements {
27  public SelectIntoStatement(SqlQueryExpression queryExpression, SqlExpression reference) {
28  if (queryExpression == null)
29  throw new ArgumentNullException("queryExpression");
30  if (reference == null)
31  throw new ArgumentNullException("reference");
32 
33  QueryExpression = queryExpression;
34  Reference = reference;
35  }
36 
37  public SqlQueryExpression QueryExpression { get; private set; }
38 
39  public SqlExpression Reference { get; private set; }
40 
41  public bool IsVariableReference {
42  get { return Reference.ExpressionType == SqlExpressionType.VariableReference; }
43  }
44 
45  public bool IsObjectReference {
46  get { return Reference.ExpressionType == SqlExpressionType.Reference; }
47  }
48 
50  var queryPlan = context.Query.Context.QueryPlanner().PlanQuery(new QueryInfo(context, QueryExpression));
51 
52  if (IsObjectReference) {
53  var tableRef = ((SqlReferenceExpression) Reference).ReferenceName;
54  return new Prepared(queryPlan, tableRef);
55  }
56 
57  if (IsVariableReference) {
58  throw new NotImplementedException();
59  }
60 
61  // Other (impossible) case...
62  throw new NotSupportedException();
63  }
64 
65  #region Prepared
66 
67  [Serializable]
69  internal Prepared(IQueryPlanNode queryPlan, ObjectName table)
70  : this(queryPlan) {
71  IsForTable = true;
72  Table = table;
73  }
74 
75  internal Prepared(IQueryPlanNode queryPlan, string varName)
76  : this(queryPlan) {
77  IsForTable = false;
78  VariableName = varName;
79  }
80 
81  private Prepared(IQueryPlanNode queryPlan) {
82  QueryPlan = queryPlan;
83  }
84 
85  private Prepared(ObjectData data) {
86  IsForTable = data.GetBoolean("IsForTable");
87  QueryPlan = data.GetValue<IQueryPlanNode>("QueryPlan");
88  Table = data.GetValue<ObjectName>("Table");
89  VariableName = data.GetString("VariableName");
90  }
91 
92  public bool IsForTable { get; private set; }
93 
94  public IQueryPlanNode QueryPlan { get; private set; }
95 
96  public ObjectName Table { get; private set; }
97 
98  public string VariableName { get; private set; }
99 
100  protected override void GetData(SerializeData data) {
101  data.SetValue("IsForTable", IsForTable);
102  data.SetValue("QueryPlan", QueryPlan);
103  data.SetValue("Table", Table);
104  data.SetValue("VariableName", VariableName);
105  }
106 
107  protected override void ExecuteStatement(ExecutionContext context) {
108  var result = QueryPlan.Evaluate(context.Request);
109 
110  if (IsForTable) {
111  var table = context.Request.Query.GetMutableTable(Table);
112  if (table == null)
113  throw new StatementPrepareException(String.Format("Referenced table of the INTO statement '{0}' was not found or is not mutable.", Table));
114 
115  SelectIntoTable(table, result);
116  }
117 
118  // TODO: get the variable from ref and check if the result is compatible and set it
119 
120  throw new NotImplementedException();
121  }
122 
123  private void SelectIntoTable(IMutableTable table, ITable result) {
124  if (!AreCompatible(table.TableInfo, result.TableInfo))
125  throw new InvalidOperationException();
126 
127 
128  for (int i = 0; i < result.RowCount; i++) {
129  var newRow = table.NewRow();
130 
131  for (int j = 0; j < result.ColumnCount(); j++) {
132  var value = result.GetValue(i, j);
133  newRow.SetValue(j, value);
134  }
135 
136  table.AddRow(newRow);
137  }
138  }
139 
140  private bool AreCompatible(TableInfo a, TableInfo b) {
141  if (a.ColumnCount != b.ColumnCount)
142  return false;
143 
144  for (int i = 0; i < a.ColumnCount; i++) {
145  var aCol = a[i];
146  var bCol = b[i];
147  if (!aCol.ColumnType.IsComparable(bCol.ColumnType))
148  return false;
149  }
150 
151  return false;
152  }
153  }
154 
155  #endregion
156  }
157 }
Defines the contract to access the data contained into a table of a database.
Definition: ITable.cs:40
void SelectIntoTable(IMutableTable table, ITable result)
An expression that references an object within a context.
An exception that happens during the SqlStatement.Prepare(IExpressionPreparer, IQueryContext).
void SetValue(string key, Type type, object value)
Describes the name of an object within a database.
Definition: ObjectName.cs:44
Prepared(IQueryPlanNode queryPlan, string varName)
DataObject GetValue(long rowNumber, int columnOffset)
Gets a single cell within the table that is located at the given column offset and row...
SqlExpressionType
All the possible type of SqlExpression supported
A node element of a query plan tree. /summary>
Represents the foundation class of SQL statements to be executed.
Definition: SqlStatement.cs:32
SelectIntoStatement(SqlQueryExpression queryExpression, SqlExpression reference)
RowId AddRow(Row row)
Persists a new row to the table.
Prepared(IQueryPlanNode queryPlan, ObjectName table)
TableInfo TableInfo
Gets the metadata information of the table, used to resolve the column sources.
Definition: ITable.cs:47
int RowCount
Gets the total number of rows in the table.
Definition: ITable.cs:52
An expression that references an object on the database (that is a Column, Table, Sequence...
int ColumnCount
Gets a count of the columns defined by this object.
Definition: TableInfo.cs:159
Defines the base class for instances that represent SQL expression tree nodes.
override void ExecuteStatement(ExecutionContext context)
Defines the metadata properties of a table existing within a database.
Definition: TableInfo.cs:41
new IQueryContext Context
Definition: IQuery.cs:21
An interface that defines contracts to alter the contents of a table.