コード例 #1
0
		protected override IReadOnlyList<OracleColumn> BuildColumns()
		{
			var columns = new List<OracleColumn>();
			var pivotColumns = new List<OracleSelectListColumn>();

			var pivotForColumnList = PivotClause[NonTerminals.PivotForClause, NonTerminals.IdentifierOrParenthesisEnclosedIdentifierList];
			if (pivotForColumnList != null)
			{
				var aggregatedColumnNames =
					SourceReferenceContainer.ColumnReferences
						.Where(c => AggregateFunctions.Any(f => f.SourcePosition.Contains(c.RootNode.SourcePosition)))
						.Select(c => c.NormalizedName);

				var groupingColumns = pivotForColumnList
					.GetDescendants(Terminals.Identifier)
					.Select(i => i.Token.Value.ToQuotedIdentifier())
					.Concat(aggregatedColumnNames)
					.ToHashSet();

				switch (PivotClause.Id)
				{
					case NonTerminals.PivotClause:
						var sourceColumns = SourceReference.Columns
							.Where(c => !groupingColumns.Contains(c.Name))
							.Select(c => c.Clone());

						columns.AddRange(sourceColumns);

						var withXmlTransformation = PivotClause[Terminals.Xml] != null;
						if (withXmlTransformation)
						{
							var xmlColumnName = String.Join("_", groupingColumns.Select(c => c.Trim('"')));
							if (xmlColumnName.Length > 26)
							{
								xmlColumnName = xmlColumnName.Substring(0, 26);
							}

							var xmlColumn =
								new OracleColumn
								{
									Name = $"\"{xmlColumnName}_XML\"",
									DataType = OracleDataType.XmlType,
									Nullable = true
								};

							columns.Add(xmlColumn);
						}
						else
						{
							pivotColumns.AddRange(ResolvePivotColumns());
							columns.AddRange(pivotColumns.Select(c => c.ColumnDescription));
						}

						break;

					case NonTerminals.UnpivotClause:
						var unpivotColumnSources = new List<StatementGrammarNode>();
						var unpivotedColumns = new HashSet<string>();
						var unpivotColumnSelectorValues = new List<StatementGrammarNode>();
						var columnTransformations = PivotClause[NonTerminals.UnpivotInClause].GetDescendants(NonTerminals.UnpivotValueToColumnTransformationList);
						var groupingColumnsNullable = false;
						foreach (var columnTransformation in columnTransformations)
						{
							unpivotedColumns.UnionWith(columnTransformation.GetDescendants(Terminals.Identifier).Select(t => t.Token.Value.ToQuotedIdentifier()));
							var columnSelectorValue = columnTransformation[NonTerminals.UnpivotValueSelector, NonTerminals.NullOrStringOrNumberLiteralOrParenthesisEnclosedStringOrIntegerLiteralList];
							if (columnSelectorValue != null)
							{
								unpivotColumnSelectorValues.Add(columnSelectorValue);
								groupingColumnsNullable |= columnSelectorValue.TerminalCount == 1 || String.Equals(columnSelectorValue.FirstTerminalNode.Id, Terminals.Null);
							}

							unpivotColumnSources.AddIfNotNull(columnTransformation[NonTerminals.IdentifierOrParenthesisEnclosedIdentifierList]);
						}

						var unpivotColumnDataTypes = OracleDataType.FromUnpivotColumnSelectorValues(unpivotColumnSelectorValues);
						AreUnpivotColumnSelectorValuesValid = unpivotColumnDataTypes != null;

						UnpivotColumnSelectorValues = unpivotColumnSelectorValues.AsReadOnly();
						UnpivotColumnSources = unpivotColumnSources.AsReadOnly();

						columns.AddRange(SourceReference.Columns
							.Where(c => !unpivotedColumns.Contains(c.Name))
							.Select(c => c.Clone()));

						columns.AddRange(groupingColumns.Select(
							(c, i) =>
								new OracleColumn
								{
									Name = c,
									Nullable = groupingColumnsNullable,
									DataType = groupingColumns.Count == unpivotColumnDataTypes?.Count
										? unpivotColumnDataTypes[i]
										: OracleDataType.Empty
								}));

						var unpivotColumnsNullable = PivotClause[NonTerminals.UnpivotNullsClause, NonTerminals.IncludeOrExclude, Terminals.Include] != null;
						var unpivotColumns = PivotClause[NonTerminals.IdentifierOrParenthesisEnclosedIdentifierList].GetDescendants(Terminals.Identifier);
						columns.AddRange(
							unpivotColumns.Select(
								i => new OracleColumn
								{
									Name = i.Token.Value.ToQuotedIdentifier(),
									DataType = OracleDataType.Empty,
									Nullable = unpivotColumnsNullable
								}));

						break;
				}
			}

			PivotColumns = pivotColumns.AsReadOnly();

			return columns.AsReadOnly();
		}