示例#1
0
		public override void Enumerate(IMemberCompletionAcceptor acceptor)
		{
			if (acceptor == null)
				throw ExceptionBuilder.ArgumentNull("acceptor");
			
			// Report all columns accessible by the table ref.
							
			TableRefBinding tableRefBinding = new TableRefBinding(null, _tableBinding, _correlationName);
			foreach (ColumnBinding columnBinding in _tableBinding.Columns)
			{
				ColumnRefBinding columnRefBinding = new ColumnRefBinding(tableRefBinding, columnBinding);
				acceptor.AcceptColumnRef(columnRefBinding);
			}
							
			// Now contribute any methods accessible by the row type.

			IMethodProvider methodProvider = _scope.DataContext.MetadataContext.MethodProviders[_tableBinding.RowType];
				
			if (methodProvider != null)
			{
				MethodBinding[] methods = methodProvider.GetMethods(_tableBinding.RowType);
				foreach (MethodBinding methodBinding in  methods)
					acceptor.AcceptMethod(methodBinding);
			}
		}
示例#2
0
		public MetaInfo(ColumnRefBinding[] columnDependencies, 
		                TableRefBinding[] tableDependencies,
		                bool containsSingleRowSubselects, 
		                bool containsExistenceSubselects)
		{
			_columnDependencies = columnDependencies;
			_tableDependencies = tableDependencies;
			_containsSingleRowSubselects = containsSingleRowSubselects;
			_containsExistenceSubselects = containsExistenceSubselects;
		}
示例#3
0
		private static JoinOrder GetBestJoinOrder(TableRefBinding[] tables, JoinCondition[] joinConditions, ICollection<ExpressionNode> andParts)
		{
			// Compute all join orders

			JoinOrderGenerator generator = new JoinOrderGenerator(joinConditions, tables);
			JoinOrder[] allJoinOrders = generator.GenerateAll();

			// Compute best join order

			JoinOrder bestJoinOrder = GetBestJoinOrder(allJoinOrders, andParts, tables);
			return bestJoinOrder;
		}
示例#4
0
		private static ColumnRefBinding CreateRowColumnRefBinding(TableRefBinding tableRefBinding)
		{
			RowColumnBinding rowColumnBinding = new RowColumnBinding(tableRefBinding.TableBinding);
			ColumnRefBinding rowColumnRefBinding = new ColumnRefBinding(tableRefBinding, rowColumnBinding);

			RowBufferEntry rowColumnBufferEntry = new RowBufferEntry(rowColumnRefBinding.ColumnBinding.DataType);
			rowColumnBufferEntry.Name = rowColumnRefBinding.TableRefBinding.Name;

			ColumnValueDefinition rowColumnValueDefinition = new ColumnValueDefinition();
			rowColumnValueDefinition.Target = rowColumnBufferEntry;
			rowColumnValueDefinition.ColumnRefBinding = rowColumnRefBinding;

			rowColumnRefBinding.ValueDefinition = rowColumnValueDefinition;
			return rowColumnRefBinding;
		}
示例#5
0
		private static JoinOrder GetBestJoinOrder(JoinOrder[] orders, ICollection<ExpressionNode> andParts, TableRefBinding[] tables)
		{
			// OK, now we try to find the best join order.
			//
			// To choose the best join order we will use a point system and score each possibility.
			// The more points a possibility has the better it is.
			//
			// To ensure we exclude as much rows as possible and as early as possible
			// we will use the count of conditions applicable to each combinations.
			//
			// A condition is said to be applicable if all referenced tables are already
			// joined. For example if we have to join four tables T1, T2, T3, T4. Accordding to
			// the join order T1 -> T2 -> T3 -> T4 the condition c is said to be applicable
			// at join index 0 if it only references columns of table T1, at index 1 if it
			// only references columns of tables T1 and T2 and so on.

			// Determine minimal count of cross joins

			int minCrossJoinCount = int.MaxValue;

			for (int i = 0; i < orders.Length; i++)
			{
				int crossJoinCount = GetCrossJoinCount(orders[i]);

				if (crossJoinCount < minCrossJoinCount)
					minCrossJoinCount = crossJoinCount;
			}

			int[] points = new int[orders.Length];

			for (int i = 0; i < orders.Length; i++)
			{
				points[i] = GetJoinOrderScore(orders[i], andParts, tables);

				if (GetCrossJoinCount(orders[i]) > minCrossJoinCount)
				{
					// If the current join order uses more cross joins than
					// the minimal one we reject this join order by setting
					// its score to minus one.
					points[i] = -1;
				}
			}

			Array.Sort(points, orders);
			JoinOrder bestJoinOrder = orders[orders.Length - 1];

			return bestJoinOrder;
		}
示例#6
0
        private static ColumnRefBinding CreateRowColumnRefBinding(TableRefBinding tableRefBinding)
        {
            RowColumnBinding rowColumnBinding    = new RowColumnBinding(tableRefBinding.TableBinding);
            ColumnRefBinding rowColumnRefBinding = new ColumnRefBinding(tableRefBinding, rowColumnBinding);

            RowBufferEntry rowColumnBufferEntry = new RowBufferEntry(rowColumnRefBinding.ColumnBinding.DataType);

            rowColumnBufferEntry.Name = rowColumnRefBinding.TableRefBinding.Name;

            ColumnValueDefinition rowColumnValueDefinition = new ColumnValueDefinition();

            rowColumnValueDefinition.Target           = rowColumnBufferEntry;
            rowColumnValueDefinition.ColumnRefBinding = rowColumnRefBinding;

            rowColumnRefBinding.ValueDefinition = rowColumnValueDefinition;
            return(rowColumnRefBinding);
        }
示例#7
0
 void IErrorReporter.InvalidRowReference(SourceRange sourceRange, TableRefBinding derivedTableRef)
 {
     string message = String.Format(CultureInfo.CurrentCulture, Resources.InvalidRowReference, derivedTableRef.Name);
     HandleError(sourceRange, ErrorId.InvalidRowReference, message);
 }
示例#8
0
 void IErrorReporter.AmbiguousTableRef(SourceRange sourceRange, Identifier identifier, TableRefBinding[] candidates)
 {
     string message = String.Format(CultureInfo.CurrentCulture, Resources.AmbiguousTableRef, identifier, FormattingHelpers.FormatBindingList(candidates));
     HandleError(sourceRange, ErrorId.AmbiguousTableRef, message);
 }
示例#9
0
		public NullRejectionChecker(TableRefBinding nullableTableRefBinding)
		{
			_nullableTableRefBinding = nullableTableRefBinding;
		}
示例#10
0
		public void AcceptRelation(TableRefBinding parentTableRef, TableRefBinding childTableRef, TableRelation relation)
		{
		}
示例#11
0
        private ColumnRefBinding ResolveColumnRef(TableRefBinding tableRef, SourceRange sourceRange, Identifier identifier)
        {
            QueryScope lookupScope = tableRef.Scope;

            ColumnRefBinding[] candidates = lookupScope.FindColumnRef(tableRef, identifier);

            if (candidates == null || candidates.Length == 0)
                return null;

            if (candidates.Length > 1)
                ErrorReporter.AmbiguousColumnRef(sourceRange, identifier, candidates);

            return candidates[0];
        }
示例#12
0
		public void SwapSides()
		{
			ExpressionNode oldLeftExpression = _leftExpression;
			TableRefBinding oldLeftTable = _leftTable;

			_op = SwapJoinOperator(_op);
			_leftExpression = _rightExpression;
			_leftTable = _rightTable;
			_rightExpression = oldLeftExpression;
			_rightTable = oldLeftTable;
		}
示例#13
0
			public override AlgebraNode VisitTableAlgebraNode(TableAlgebraNode node)
			{
				TableRefBinding oldTableRefBinding = node.TableRefBinding;
				TableRefBinding newTableRefBinding = new TableRefBinding(oldTableRefBinding.Scope, oldTableRefBinding.TableBinding, oldTableRefBinding.Name);

				List<ColumnValueDefinition> definedValues = new List<ColumnValueDefinition>();
				for (int i = 0; i < newTableRefBinding.ColumnRefs.Length; i++)
				{
					definedValues.Add(newTableRefBinding.ColumnRefs[i].ValueDefinition);
					RowBufferEntry oldRowBufferEntry = oldTableRefBinding.ColumnRefs[i].ValueDefinition.Target;
					RowBufferEntry newRowBufferEntry = newTableRefBinding.ColumnRefs[i].ValueDefinition.Target;
					_rowBufferMappings.Add(oldRowBufferEntry, newRowBufferEntry);
				}

				node.TableRefBinding = newTableRefBinding;
				node.DefinedValues = definedValues.ToArray();

				return node;
			}
示例#14
0
		public void AcceptTableRef(TableRefBinding tableRef)
		{
		}
示例#15
0
		public JoinOrderGenerator(JoinCondition[] joinConditions, TableRefBinding[] tables)
		{
			_joinConditions = joinConditions;		
			_tables = tables;		
		}
示例#16
0
		public void AcceptTableRef(TableRefBinding tableRef)
		{
			Add(tableRef.Name, tableRef.GetFullName(), "TABLE REF", TABLE_REF_IMG_INDEX);
		}
示例#17
0
		private static ExpressionNode ExtractConditionsApplicableToTable(IDictionary<RowBufferEntry, ColumnValueDefinition> introducedColumns, IList<ExpressionNode> conditionList, TableRefBinding tableRefBinding)
		{
			List<ExpressionNode> applicableConditionList = new List<ExpressionNode>();

			for (int i = conditionList.Count - 1; i >= 0; i--)
			{
				ExpressionNode condition = conditionList[i];
				RowBufferEntry[] rowBufferEntries = AstUtil.GetRowBufferEntryReferences(condition);

				bool dependentOnOtherTable = false;
				foreach (RowBufferEntry rowBufferEntry in rowBufferEntries)
				{
					ColumnValueDefinition columnValueDefinition;
					if (introducedColumns.TryGetValue(rowBufferEntry, out columnValueDefinition))
					{
						if (columnValueDefinition.ColumnRefBinding.TableRefBinding != tableRefBinding)
						{
							dependentOnOtherTable = true;
							break;
						}
					}
				}

				if (!dependentOnOtherTable)
				{
					conditionList.RemoveAt(i);
					applicableConditionList.Add(condition);
				}
			}

			if (applicableConditionList.Count == 0)
				return null;

			ExpressionNode[] applicableConditions = applicableConditionList.ToArray();
			return AstUtil.CombineConditions(LogicalOperator.And, applicableConditions);
		}
示例#18
0
		private void WriteTableRef(TableRefBinding tableRefBinding)
		{
			_xmlWriter.WriteAttributeString("table", tableRefBinding.TableBinding.Name);
			_xmlWriter.WriteAttributeString("tableRef", tableRefBinding.Name);
		}
示例#19
0
		public ColumnRefBinding(TableRefBinding tableRefBinding, ColumnBinding columnBinding)
		{
			_tableRefBinding = tableRefBinding;
			_columnBinding = columnBinding;
		}
示例#20
0
		private static AlgebraNode InstantiateCte(AlgebraNode algebrizedCte, CommonTableBinding commonTableBinding, TableRefBinding commonTableRefBinding)
		{
			// Replace row buffers to base tables by new ones. This must be done because a CTE could be referenced multiple times.
			// Since same row buffer entries means that the underlying data will be stored in the same physical data slot this
			// will lead to problems if, for example, two instances of the same CTE are joined together. Any join condition that
			// operates on the same column will always compare data coming from the same join side (and therefor will always
			// evaluate to true).
			//
			// Some notes on the implementation:
			//
			//      1. Note that just replacing references to row buffers of base tables in RowBufferExpression is not enough;
			//         instead they must also be replaced in output lists, defined value references (esp. ConcatAlgebraNode) etc.
			//      2. Also note that although the QueryNodes are re-algebrized every time a CTE is references the expressions
			//         are still copied from the QueryNodes (instead of cloned). Therefore two algrebrized CTEs will share the same
			//         expression AST instances. That means that replacing the row buffers leads to failure.

			// HACK: This is a workaround for issue 2. However, 
			//       I am not quite sure how one should implement row buffer entry replacement without cloning the algebrized query.
			algebrizedCte = (AlgebraNode) algebrizedCte.Clone();

			CteTableDefinedValuesReinitializer cteTableDefinedValuesReinitializer = new CteTableDefinedValuesReinitializer();
			cteTableDefinedValuesReinitializer.Visit(algebrizedCte);

			RowBufferEntry[] outputList = algebrizedCte.OutputList;
			int skipRecursionLevel = commonTableBinding.IsRecursive ? 1 : 0;

			// Rename the query columns to the CTE columns
			List<ComputedValueDefinition> definedValues = new List<ComputedValueDefinition>();
			for (int i = 0; i < commonTableRefBinding.ColumnRefs.Length; i++)
			{
				RowBufferEntry targetRowBufferEntry = commonTableRefBinding.ColumnRefs[i].ValueDefinition.Target;
				RowBufferEntry sourceRowBufferEntry = outputList[i + skipRecursionLevel];

				ComputedValueDefinition definedValue = new ComputedValueDefinition();
				definedValue.Target = targetRowBufferEntry;
				definedValue.Expression = new RowBufferEntryExpression(sourceRowBufferEntry);
				definedValues.Add(definedValue);
			}

			ComputeScalarAlgebraNode computeScalarAlgebraNode = new ComputeScalarAlgebraNode();
			computeScalarAlgebraNode.Input = algebrizedCte;
			computeScalarAlgebraNode.DefinedValues = definedValues.ToArray();
			return computeScalarAlgebraNode;
		}
示例#21
0
 void IErrorReporter.TableRefInaccessible(TableRefBinding tableRefBinding)
 {
     string message = String.Format(CultureInfo.CurrentCulture, Resources.TableRefInaccessible, tableRefBinding.Name, tableRefBinding.TableBinding.Name);
     HandleError(ErrorId.TableRefInaccessible, message);
 }
示例#22
0
 void IErrorReporter.UndeclaredColumn(SourceRange sourceRange, TableRefBinding tableRefBinding, Identifier identifier)
 {
     string message = String.Format(CultureInfo.CurrentCulture, Resources.UndeclaredColumn, tableRefBinding.Name, identifier);
     HandleError(sourceRange, ErrorId.UndeclaredColumn, message);
 }
示例#23
0
 public ColumnRefBinding(TableRefBinding tableRefBinding, ColumnBinding columnBinding)
 {
     _tableRefBinding = tableRefBinding;
     _columnBinding   = columnBinding;
 }
示例#24
0
		public void AcceptRelation(TableRefBinding parentBinding, TableRefBinding childBinding, TableRelation relation)
		{
			ColumnBindingCollection parentColumns;
			if (parentBinding.TableBinding == relation.ParentTable)
				parentColumns = relation.ParentColumns;
			else
				parentColumns = relation.ChildColumns;

			ColumnBindingCollection childColumns;
			if (childBinding.TableBinding == relation.ChildTable)
				childColumns = relation.ChildColumns;
			else
				childColumns = relation.ParentColumns;

			// Item in member list:
			// ~~~~~~~~~~~~~~~~~~~~
			// parentRef(col1, col2) ---> childRef(col1, col2)
				
			StringBuilder sb = new StringBuilder();
			sb.Append(parentBinding.Name);
			sb.Append(" (");
			for (int i = 0; i < relation.ColumnCount; i++)
			{
				if (i > 0)
					sb.Append(", ");
					
				sb.Append(parentColumns[i].Name);
			}
			sb.Append(") ---> ");
			sb.Append(childBinding.Name);
			sb.Append(" (");
			for (int i = 0; i < relation.ColumnCount; i++)
			{
				if (i > 0)
					sb.Append(", ");
					
				sb.Append(childColumns[i].Name);
			}
			sb.Append(")");

			string name = sb.ToString();
			sb.Length = 0;
				
			// Description:
			// ~~~~~~~~~~~~
			// Relation <b>parentTable parentRef</b> ---> <b>ChildTable childRef</b> <br/>
			// ON (parentRef.Col1 = childRef.Col1 AND parentRef.Col2 = childRef.Col2)
				
			sb.Append("Relation <br/>");
			sb.Append("<b>");
			sb.Append(MaskIdentifier(parentBinding.TableBinding.Name));
			sb.Append(" AS ");
			sb.Append(MaskIdentifier(parentBinding.Name));
			sb.Append("</b>");
			sb.Append(" ---> ");
			sb.Append("<b>");
			sb.Append(MaskIdentifier(childBinding.TableBinding.Name));
			sb.Append(" AS ");
			sb.Append(MaskIdentifier(childBinding.Name));
			sb.Append("</b><br/>ON (");
				
			for (int i = 0; i < relation.ColumnCount; i++)
			{
				if (i > 0)
					sb.Append(" AND ");
					
				sb.Append(MaskIdentifier(parentBinding.Name));
				sb.Append(".");
				sb.Append(MaskIdentifier(parentColumns[i].Name));
				sb.Append(" = ");
				sb.Append(MaskIdentifier(childBinding.Name));
				sb.Append(".");
				sb.Append(MaskIdentifier(childColumns[i].Name));
			}
			sb.Append(")");
				
			string description = sb.ToString();
			sb.Length = 0;
				
			// PreText:
			// ~~~~~~~~
			// parentAlias.Col1 = childAlias.Col1 AND parentAlias.Col2 = childAlias.Col2
				
			for (int i = 0; i < relation.ColumnCount; i++)
			{
				if (i > 0)
					sb.Append(" AND ");
					
				sb.Append(MaskIdentifier(parentBinding.Name));
				sb.Append(".");
				sb.Append(MaskIdentifier(parentColumns[i].Name));
				sb.Append(" = ");
				sb.Append(MaskIdentifier(childBinding.Name));
				sb.Append(".");
				sb.Append(MaskIdentifier(childColumns[i].Name));
			}

			string preText = sb.ToString();
			sb.Length = 0;
				
			IntelliPromptMemberListItem item = new IntelliPromptMemberListItem(name, RELATION_IMG_INDEX, description, preText, String.Empty);
			_members.Add(item);												
		}
示例#25
0
		private static int GetJoinOrderScore(JoinOrder joinOder, ICollection<ExpressionNode> andParts, TableRefBinding[] tables)
		{
			int result = 0;

			Dictionary<RowBufferEntry, ColumnValueDefinition> introducedColumns = GetIntroducedColumns(joinOder);
            
			for (int joinIndex = 0; joinIndex < tables.Length; joinIndex++)
			{
				ExpressionNode[] applicableConditions = GetAndPartsApplicableToJoin(introducedColumns, joinOder, joinIndex, andParts, false);

				result *= 2;
				result += applicableConditions.Length;

				if (joinOder.Joins[joinIndex].JoinCondition != null)
					result += 1;
			}

			return result;
		}
示例#26
0
		private void Join(TableRefBinding table, JoinCondition joinCondition)
		{
			_usedTableList.Add(table);
			_usedJoinConditionList.Add(joinCondition);

			if (_usedTableList.Count == _tables.Length)
			{
				// We have joined all tables, create the join order.
				//
				// First we create a list of the join conditions we used.

				List<Join> joinList = new List<Join>();

				for (int i = 0; i < _usedTableList.Count; i++)
				{
					TableRefBinding usedTable = _usedTableList[i];
					JoinCondition usedJoinCondition = _usedJoinConditionList[i];
						
					// The first entry will be null, since we do not join from anywhere 

					if (usedJoinCondition != null)
					{
						// Since we swapping the join sides according to the direction
						// we are joining from we need to create a clone. The clone
						// is a flat copy meaning that the tables and expressions
						// themselves are not cloned.

						usedJoinCondition = usedJoinCondition.Clone();

						// If the right table is not the table we are joining to
						// swap the join sides.

						if (usedJoinCondition.RightTable != usedTable)
							usedJoinCondition.SwapSides();
					}

					Join join = new Join();
					join.JoinCondition = usedJoinCondition;
					join.TableRefBinding = usedTable;

					joinList.Add(join);
				}

				// Secondly and very important: We also have to create a list of all
				// join conditions NOT used. Later theses conditions will be combined
				// with the and-parts since they must also be checked.

				List<ExpressionNode> unusedConditionList = new List<ExpressionNode>();

				foreach (JoinCondition jc in _joinConditions)
				{
					if (!_usedJoinConditionList.Contains(jc))
						unusedConditionList.Add(jc.ToExpression());
				}

				JoinOrder joinOrder = new JoinOrder();
				joinOrder.Joins = joinList.ToArray();
				joinOrder.UnusedConditions = unusedConditionList.ToArray();

				_joinOrderList.Add(joinOrder);
			}
			else
			{
				// We are not yet finished with all tables. Find next table
				// to join with.

				bool hasJoin = false;

				foreach (JoinCondition nextJoin in _joinConditions)
				{
					if (!_usedJoinConditionList.Contains(nextJoin))
					{
						TableRefBinding nextTable;

						if (_usedTableList.Contains(nextJoin.LeftTable))
						{
							nextTable = nextJoin.RightTable;
						}
						else if (_usedTableList.Contains(nextJoin.RightTable))
						{
							nextTable = nextJoin.LeftTable;
						}
						else
						{
							continue;
						}

						if (_usedTableList.Contains(nextTable))
							continue;

						Join(nextTable, nextJoin);
						hasJoin = true;
					}
				}

				if (!hasJoin)
				{
					foreach (TableRefBinding t in _tables)
					{
						if (!_usedTableList.Contains(t))
							Join(t, null);
					}
				}
			}

			_usedJoinConditionList.RemoveAt(_usedJoinConditionList.Count - 1);
			_usedTableList.RemoveAt(_usedTableList.Count - 1);
		}
示例#27
0
		private void AddTable(TableRefBinding table)
		{
			if (IsOuterScope(table.Scope) && !_tableBindingList.Contains(table))
				_tableBindingList.Add(table);
		}