Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions SqlScriptDom/Parser/TSql/Ast.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1459,6 +1459,10 @@
<InheritedMember Name="SchemaObjectName" ContainerClass="AlterTableStatement"/>
<Member Name="Options" Type="TableOption" Collection="true" Summary="Options to be set."/>
</Class>
<Class Name="AlterTableAddClusterByStatement" Base="AlterTableStatement" Summary="Alters a table by adding a CLUSTER BY specification.">
<InheritedMember Name="SchemaObjectName" ContainerClass="AlterTableStatement"/>
<Member Name="ClusterByOption" Type="ClusterByTableOption" Summary="The CLUSTER BY option to be added to the table."/>
</Class>
<Class Name="TableOption" Abstract="true" Summary="A single table option.">
<Member Name="OptionKind" Type="TableOptionKind" GenerateUpdatePositionInfoCall="false" Summary="The option kind."/>
</Class>
Expand Down Expand Up @@ -2674,6 +2678,9 @@
<!-- CTAS additions for SQL Dw-->
<Member Name="SelectStatement" Type="SelectStatement" Summary="Represents the query part of a CTAS statement."/>
<Member Name="CtasColumns" Type="Identifier" Collection="true" Summary="The columns for the view. This is optionally supported with CTAS statements."/>
<!-- CTAC additions for Fabric DW SQL-->
<Member Name="CloneSource" Type="SchemaObjectName" Summary="Source table for CLONE syntax."/>
<Member Name="ClonePointInTime" Type="ScalarExpression" Summary="Optional point in time for CLONE statement."/>
</Class>
<Class Name="FederationScheme" Summary="This class stores the federation scheme for a table">
<Member Name="DistributionName" Type="Identifier" Summary="The name of the distribution."/>
Expand Down Expand Up @@ -2706,6 +2713,11 @@
<Member Name="DistributionColumns" Type="Identifier" Collection="true" GenerateUpdatePositionInfoCall="false" Summary="The column reference in the HASH option for a table distribution policy."/>
</Class>

<!-- CLUSTER BY additions for Fabric DW SQL-->
<Class Name="ClusterByTableOption" Base="TableOption" Summary="Represents the CLUSTER BY option for tables.">
<InheritedClass Name="TableOption"/>
<Member Name="Columns" Type="ColumnReferenceExpression" Collection="true" Summary="The columns for clustering the table."/>
</Class>
<Class Name="TableIndexOption" Base="TableOption" Summary="Represents the table INDEX option for SQL DW tables.">
<InheritedClass Name="TableOption"/>
<Member Name="Value" Type="TableIndexType" GenerateUpdatePositionInfoCall="false" Summary="The table index types could be clustered or non-clustered (heap)."/>
Expand Down
1 change: 1 addition & 0 deletions SqlScriptDom/Parser/TSql/CodeGenerationSupporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ internal static class CodeGenerationSupporter
internal const string Cluster = "CLUSTER";
internal const string Clustered = "CLUSTERED";
internal const string ClearPort = "CLEAR_PORT";
internal const string Clone = "CLONE";
internal const string CodePage = "CODEPAGE";
internal const string Collection = "COLLECTION";
internal const string Column = "COLUMN";
Expand Down
134 changes: 132 additions & 2 deletions SqlScriptDom/Parser/TSql/TSqlFabricDW.g
Original file line number Diff line number Diff line change
Expand Up @@ -13006,6 +13006,93 @@ functionParameterList[FunctionStatementBody vResult]
)*
;

scalarFunctionParameter[ProcedureParameter vParent]
{
DataTypeReference vDataType;
ScalarExpression vDefault;
}
: vDataType=scalarDataType
{
vParent.DataType = vDataType;
}
(
EqualsSign
(
vDefault=possibleNegativeConstantOrIdentifierWithDefault
{
vParent.Value = vDefault;
}
)
)?
(
tId2:Identifier
{
if (TryMatch(tId2, CodeGenerationSupporter.Output) || TryMatch(tId2, CodeGenerationSupporter.Out))
{
ThrowParseErrorException("SQL46039", tId2, TSqlParserResource.SQL46039Message);
}
else
{
ThrowParseErrorException("SQL46026", tId2, TSqlParserResource.SQL46026Message, tId2.getText());
}
}
)?
;

scalarFunctionAttributeNoExecuteAs returns [FunctionOption vResult = FragmentFactory.CreateFragment<FunctionOption>()]
: tOption:Identifier
{
if (TryMatch(tOption, CodeGenerationSupporter.SchemaBinding))
{
vResult.OptionKind = FunctionOptionKind.SchemaBinding;
}
else
{
ThrowParseErrorException("SQL46026", tOption, TSqlParserResource.SQL46026Message, tOption.getText());
}
UpdateTokenInfo(vResult, tOption);
}
| tReturns:Identifier Null On Null tInput:Identifier
{
Match(tReturns,CodeGenerationSupporter.Returns);
Match(tInput,CodeGenerationSupporter.Input);
vResult.OptionKind = FunctionOptionKind.ReturnsNullOnNullInput;
UpdateTokenInfo(vResult, tInput);
}
| tCalled:Identifier On Null tInput2:Identifier
{
Match(tCalled,CodeGenerationSupporter.Called);
Match(tInput2,CodeGenerationSupporter.Input);
vResult.OptionKind = FunctionOptionKind.CalledOnNullInput;
UpdateTokenInfo(vResult, tInput2);
}
;


scalarFunctionAttribute returns [FunctionOption vResult]
: vResult=scalarFunctionAttributeNoExecuteAs
| vResult=functionExecuteAsOption
;

scalarFunctionAttributes [FunctionStatementBody vParent]
{
FunctionOption vOption;
long encounteredOptions = 0;
}
: With vOption=scalarFunctionAttribute
{
CheckOptionDuplication(ref encounteredOptions, (int)vOption.OptionKind, vOption);
AddAndUpdateTokenInfo(vParent, vParent.Options, vOption);
}
(
Comma vOption=scalarFunctionAttribute
{
CheckOptionDuplication(ref encounteredOptions, (int)vOption.OptionKind, vOption);
AddAndUpdateTokenInfo(vParent, vParent.Options, vOption);
}
)*
;

functionParameter returns[ProcedureParameter vResult = FragmentFactory.CreateFragment<ProcedureParameter>()]
{
Identifier vIdentifier;
Expand All @@ -13014,7 +13101,7 @@ functionParameter returns[ProcedureParameter vResult = FragmentFactory.CreateFra
{
vResult.VariableName = vIdentifier;
}
scalarProcedureParameter[vResult, false, true]
scalarFunctionParameter[vResult]
;

functionReturnTypeAndBody [FunctionStatementBody vParent, out bool vParseErrorOccurred]
Expand All @@ -13034,7 +13121,7 @@ functionReturnTypeAndBody [FunctionStatementBody vParent, out bool vParseErrorOc
vScalarResult.DataType = vDataType;
vParent.ReturnType = vScalarResult;
}
(functionAttributes[vParent])? (As)?
(scalarFunctionAttributes[vParent])? (As)?
(
vCompoundStatement = beginEndBlockStatement
{
Expand Down Expand Up @@ -26504,6 +26591,8 @@ createTableStatement returns [CreateTableStatement vResult = this.FragmentFactor
TableDefinition vTableDefinition;
FederationScheme vFederationScheme;
FileGroupOrPartitionScheme vFileGroupOrPartitionScheme;
SchemaObjectName vCloneSource;
ScalarExpression vCloneTime;
}
: tCreate:Create Table vSchemaObjectName=schemaObjectThreePartName
{
Expand Down Expand Up @@ -26534,6 +26623,19 @@ createTableStatement returns [CreateTableStatement vResult = this.FragmentFactor
)
|
ctasCreateTableStatement[vResult]
|
As tClone:Identifier Of vCloneSource=schemaObjectThreePartName
{
Match(tClone, CodeGenerationSupporter.Clone);
vResult.CloneSource = vCloneSource;
}
(
tAt:Identifier vCloneTime=stringLiteral
{
Match(tAt, CodeGenerationSupporter.At);
vResult.ClonePointInTime = vCloneTime;
}
)?
|
As tFileTableOrGraphEdge:Identifier
{
Expand Down Expand Up @@ -26735,6 +26837,9 @@ createTableOption returns [TableOption vResult]
|
{NextTokenMatches(CodeGenerationSupporter.Distribution)}?
vResult = tableDistributionOption
|
{NextTokenMatches(CodeGenerationSupporter.Cluster)}?
vResult = clusterByTableOption
|
vResult = tableIndexOption
|
Expand Down Expand Up @@ -26961,6 +27066,15 @@ tableRoundRobinDistributionPolicy returns [TableRoundRobinDistributionPolicy vRe
}
;

clusterByTableOption returns [ClusterByTableOption vResult = this.FragmentFactory.CreateFragment<ClusterByTableOption>()]
: tCluster:Identifier By
{
Match(tCluster, CodeGenerationSupporter.Cluster);
UpdateTokenInfo(vResult, tCluster);
}
identifierColumnList[vResult, vResult.Columns]
;

tableIndexOption returns [TableIndexOption vResult = FragmentFactory.CreateFragment<TableIndexOption>()]
{
TableIndexType vTableIndexType;
Expand Down Expand Up @@ -27898,6 +28012,7 @@ alterTableStatement returns [AlterTableStatement vResult = null]
{NextTokenMatches(CodeGenerationSupporter.FileTableNamespace, 2)}?
vResult=alterTableFileTableNamespaceStatement
| vResult=alterTableSetStatement
| vResult=alterTableAddClusterByStatement
)
{
// Update position later, because instantiation is lazy
Expand Down Expand Up @@ -28040,6 +28155,21 @@ alterTableSetStatement returns [AlterTableSetStatement vResult = FragmentFactory
}
;

alterTableAddClusterByStatement returns [AlterTableAddClusterByStatement vResult = FragmentFactory.CreateFragment<AlterTableAddClusterByStatement>()]
{
ClusterByTableOption vClusterByOption;
}
: tAdd:Add LeftParenthesis vClusterByOption = clusterByTableOption
{
vResult.ClusterByOption = vClusterByOption;
UpdateTokenInfo(vResult, tAdd);
}
tRParen:RightParenthesis
{
UpdateTokenInfo(vResult, tRParen);
}
;

tableOption returns [TableOption vResult = null]
:
{NextTokenMatches(CodeGenerationSupporter.LockEscalation)}?
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//------------------------------------------------------------------------------
// <copyright file="SqlScriptGeneratorVisitor.AlterTableAddClusterByStatement.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using Microsoft.SqlServer.TransactSql.ScriptDom;

namespace Microsoft.SqlServer.TransactSql.ScriptDom.ScriptGenerator
{
partial class SqlScriptGeneratorVisitor
{
public override void ExplicitVisit(AlterTableAddClusterByStatement node)
{
AlignmentPoint start = new AlignmentPoint();
MarkAndPushAlignmentPoint(start);

GenerateAlterTableHead(node);

NewLineAndIndent();

GenerateKeyword(TSqlTokenType.Add);
GenerateSpace();
if (node.ClusterByOption != null)
{
GenerateSymbol(TSqlTokenType.LeftParenthesis);
GenerateFragmentIfNotNull(node.ClusterByOption);
GenerateSymbol(TSqlTokenType.RightParenthesis);
}

PopAlignmentPoint();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//------------------------------------------------------------------------------
// <copyright file="SqlScriptGeneratorVisitor.ClusterByTableOption.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using Microsoft.SqlServer.TransactSql.ScriptDom;

namespace Microsoft.SqlServer.TransactSql.ScriptDom.ScriptGenerator
{
partial class SqlScriptGeneratorVisitor
{
public override void ExplicitVisit(ClusterByTableOption node)
{
GenerateIdentifier(CodeGenerationSupporter.Cluster);
GenerateSpaceAndKeyword(TSqlTokenType.By);
GenerateSpace();
GenerateParenthesisedCommaSeparatedList(node.Columns);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@ public override void ExplicitVisit(CreateTableStatement node)

GenerateSpaceAndFragmentIfNotNull(node.SchemaObjectName);

if (node.CloneSource != null)
{
GenerateSpaceAndKeyword(TSqlTokenType.As);
GenerateSpaceAndIdentifier(CodeGenerationSupporter.Clone);
GenerateSpaceAndKeyword(TSqlTokenType.Of);
GenerateSpaceAndFragmentIfNotNull(node.CloneSource);

if (node.ClonePointInTime != null)
{
GenerateSpaceAndIdentifier(CodeGenerationSupporter.At);
GenerateSpaceAndFragmentIfNotNull(node.ClonePointInTime);
}
}

if (node.Definition != null)
{
List<TSqlFragment> columnsAndConstraintsAndIndexesAndPeriods = new List<TSqlFragment>();
Expand Down
7 changes: 7 additions & 0 deletions Test/SqlDom/BaselinesFabricDW/CloneTableTestsFabricDW.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE dbo.Employee AS CLONE OF dbo.EmployeeUSA;

CREATE TABLE dbo.Employee AS CLONE OF dbo1.EmployeeUSA;

CREATE TABLE dbo.Employee AS CLONE OF dbo.EmployeeUSA AT '2023-05-23T14:24:10.325';

CREATE TABLE dbo.Employee AS CLONE OF dbo1.EmployeeUSA AT '2023-05-23T14:24:10';
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
CREATE TABLE Customers (
CustomerID INT ,
Name NVARCHAR (100)
)
WITH (CLUSTER BY (CustomerID));


GO
CREATE TABLE sales.Orders (
OrderID INT ,
CustomerID INT ,
OrderDate DATE
)
WITH (CLUSTER BY (CustomerID, OrderDate), DISTRIBUTION = HASH(CustomerID));


GO
CREATE TABLE Inventory (
ProductID INT ,
ProductName VARCHAR (255),
InStock BIT
)
WITH (CLUSTER BY (ProductID));


GO
ALTER TABLE Customers
ADD (CLUSTER BY (CustomerID));


GO
ALTER TABLE sales.Orders
ADD (CLUSTER BY (CustomerID, OrderDate));


GO
ALTER TABLE Inventory
ADD (CLUSTER BY (ProductID));
Loading
Loading