Visitar URL original
Make MODEL_TYPE fragment classification non-breaking (#217) · codezerg/SqlScriptDOM@2337cea · GitHub
Skip to content

Commit 2337cea

Browse files
authored
Make MODEL_TYPE fragment classification non-breaking (microsoft#217)
Commit 20f9bf1 (PR microsoft#210, fixing microsoft#176) reclassified MODEL_TYPE as a TSqlFragment but broke the public API: it repurposed the enum ExternalModelTypeOption into a fragment class and changed the type of ExternalModelStatement.ModelType from ExternalModelTypeOption? to a fragment reference. This change delivers the same fix additively, without breaking the API: - Keep enum ExternalModelTypeOption { EMBEDDINGS } and the ExternalModelStatement.ModelType (ExternalModelTypeOption?) member unchanged for backward compatibility. - Add a visitable fragment ExternalModelTypeSpecification whose OptionKind reuses the existing ExternalModelTypeOption enum, plus a new ModelTypeSpecification member on ExternalModelStatement. - The parser populates both representations; the script generator prefers the fragment and falls back to the legacy enum. All 624 unit tests pass on net8.0 and net472.
1 parent bb623c8 commit 2337cea

7 files changed

Lines changed: 65 additions & 35 deletions

File tree

‎SqlScriptDom/Parser/TSql/Ast.xml‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,7 +1388,8 @@
13881388
<Member Name="Name" Type="Identifier" Summary="The external model name."/>
13891389
<Member Name="Location" Type="Literal" Summary="The external model location name."/>
13901390
<Member Name="ApiFormat" Type="Literal" Summary="The external model api format name."/>
1391-
<Member Name="ModelType" Type="ExternalModelTypeOption" Summary="The external model type name."/>
1391+
<Member Name="ModelType" Type="ExternalModelTypeOption?" GenerateUpdatePositionInfoCall="false" Summary="The external model type name. Retained for backward compatibility; prefer ModelTypeSpecification."/>
1392+
<Member Name="ModelTypeSpecification" Type="ExternalModelTypeSpecification" Summary="The MODEL_TYPE option as a visitable fragment."/>
13921393
<Member Name="ModelName" Type="Literal" Summary="The external model name to be used to generate embeddings."/>
13931394
<Member Name="Credential" Type="Identifier" Summary="The external model credentials name."/>
13941395
<Member Name="Parameters" Type="Literal" Summary="The external model parameters as key-value pairs."/>
@@ -1404,8 +1405,8 @@
14041405
<Class Name="AlterExternalModelStatement" Base="ExternalModelStatement" Summary="Represents a ALTER EXTERNAL MODEL statement.">
14051406
<InheritedClass Name="ExternalModelStatement"/>
14061407
</Class>
1407-
<Class Name="ExternalModelTypeOption" Base="TSqlFragment" Summary="Represents the MODEL_TYPE option in CREATE/ALTER EXTERNAL MODEL.">
1408-
<Member Name="OptionKind" Type="ExternalModelTypeOptionKind" GenerateUpdatePositionInfoCall="false" Summary="The option kind."/>
1408+
<Class Name="ExternalModelTypeSpecification" Base="TSqlFragment" Summary="Represents the MODEL_TYPE option in CREATE/ALTER EXTERNAL MODEL.">
1409+
<Member Name="OptionKind" Type="ExternalModelTypeOption" GenerateUpdatePositionInfoCall="false" Summary="The option kind."/>
14091410
</Class>
14101411

14111412
<Class Name="ExternalFileFormatStatement" Abstract="true" Base="TSqlStatement" Summary="Base class for all external file format statement objects.">

‎SqlScriptDom/Parser/TSql/ExternalModelTypeOption.cs‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@ namespace Microsoft.SqlServer.TransactSql.ScriptDom
1010
#pragma warning disable 1591
1111

1212
/// <summary>
13-
/// The enumeration specifies the external model type
14-
/// Currently, we support Embeddings only.
13+
/// The enumeration specifies the external model type.
14+
/// Currently, we support EMBEDDINGS only.
1515
/// </summary>
16-
public enum ExternalModelTypeOptionKind
16+
public enum ExternalModelTypeOption
1717
{
1818
/// <summary>
1919
/// MODEL_TYPE = EMBEDDINGS
2020
/// </summary>
21-
Embeddings = 0,
22-
21+
EMBEDDINGS = 0,
2322
}
2423

2524
#pragma warning restore 1591

‎SqlScriptDom/Parser/TSql/TSql170.g‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24171,25 +24171,26 @@ StringLiteral vApiFormat;
2417124171

2417224172
externalModelModelType[ExternalModelStatement vParent]
2417324173
{
24174-
ExternalModelTypeOption vModelTypeOption = null;
24174+
ExternalModelTypeSpecification vModelTypeSpec = null;
2417524175
}
2417624176
:
2417724177
tModelType:Identifier
2417824178
{
2417924179
Match(tModelType, CodeGenerationSupporter.ModelType);
24180-
vModelTypeOption = this.FragmentFactory.CreateFragment<ExternalModelTypeOption>();
24181-
UpdateTokenInfo(vModelTypeOption, tModelType);
24180+
vModelTypeSpec = this.FragmentFactory.CreateFragment<ExternalModelTypeSpecification>();
24181+
UpdateTokenInfo(vModelTypeSpec, tModelType);
2418224182
}
2418324183
EqualsSign
2418424184
(
2418524185
tEmbeddings:Identifier
2418624186
{
2418724187
if (TryMatch(tEmbeddings, CodeGenerationSupporter.Embeddings))
2418824188
{
24189-
vModelTypeOption.OptionKind = ExternalModelTypeOptionKind.Embeddings;
24190-
UpdateTokenInfo(vModelTypeOption, tEmbeddings);
24191-
vParent.ModelType = vModelTypeOption;
24192-
vParent.UpdateTokenInfo(vModelTypeOption);
24189+
vModelTypeSpec.OptionKind = ExternalModelTypeOption.EMBEDDINGS;
24190+
UpdateTokenInfo(vModelTypeSpec, tEmbeddings);
24191+
vParent.ModelTypeSpecification = vModelTypeSpec;
24192+
vParent.ModelType = ExternalModelTypeOption.EMBEDDINGS;
24193+
vParent.UpdateTokenInfo(vModelTypeSpec);
2419324194
}
2419424195
else
2419524196
{

‎SqlScriptDom/Parser/TSql/TSql180.g‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24400,25 +24400,26 @@ StringLiteral vApiFormat;
2440024400

2440124401
externalModelModelType[ExternalModelStatement vParent]
2440224402
{
24403-
ExternalModelTypeOption vModelTypeOption = null;
24403+
ExternalModelTypeSpecification vModelTypeSpec = null;
2440424404
}
2440524405
:
2440624406
tModelType:Identifier
2440724407
{
2440824408
Match(tModelType, CodeGenerationSupporter.ModelType);
24409-
vModelTypeOption = this.FragmentFactory.CreateFragment<ExternalModelTypeOption>();
24410-
UpdateTokenInfo(vModelTypeOption, tModelType);
24409+
vModelTypeSpec = this.FragmentFactory.CreateFragment<ExternalModelTypeSpecification>();
24410+
UpdateTokenInfo(vModelTypeSpec, tModelType);
2441124411
}
2441224412
EqualsSign
2441324413
(
2441424414
tEmbeddings:Identifier
2441524415
{
2441624416
if (TryMatch(tEmbeddings, CodeGenerationSupporter.Embeddings))
2441724417
{
24418-
vModelTypeOption.OptionKind = ExternalModelTypeOptionKind.Embeddings;
24419-
UpdateTokenInfo(vModelTypeOption, tEmbeddings);
24420-
vParent.ModelType = vModelTypeOption;
24421-
vParent.UpdateTokenInfo(vModelTypeOption);
24418+
vModelTypeSpec.OptionKind = ExternalModelTypeOption.EMBEDDINGS;
24419+
UpdateTokenInfo(vModelTypeSpec, tEmbeddings);
24420+
vParent.ModelTypeSpecification = vModelTypeSpec;
24421+
vParent.ModelType = ExternalModelTypeOption.EMBEDDINGS;
24422+
vParent.UpdateTokenInfo(vModelTypeSpec);
2442224423
}
2442324424
else
2442424425
{

‎SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGenerator.AlterExternalModelStatement.cs‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,26 @@ protected void GenerateAlterExternalModelStatementBody(AlterExternalModelStateme
5353
}
5454

5555
// external model Model Type options
56-
if (node.ModelType != null)
56+
if (node.ModelTypeSpecification != null)
5757
{
5858
if (!ifFirst)
5959
{
6060
GenerateSymbol(TSqlTokenType.Comma);
6161
}
6262
ifFirst = false;
6363
NewLine();
64-
GenerateFragmentIfNotNull(node.ModelType);
64+
GenerateFragmentIfNotNull(node.ModelTypeSpecification);
65+
}
66+
else if (node.ModelType != null)
67+
{
68+
if (!ifFirst)
69+
{
70+
GenerateSymbol(TSqlTokenType.Comma);
71+
}
72+
ifFirst = false;
73+
NewLine();
74+
string externalModelTypeOption = GetValueForEnumKey(_externalModelTypeOption, node.ModelType.Value);
75+
GenerateNameEqualsValue(CodeGenerationSupporter.ModelType, externalModelTypeOption);
6576
}
6677

6778
// external model name options

‎SqlScriptDom/ScriptDom/SqlServer/ScriptGenerator/SqlScriptGeneratorVisitor.CreateExternalModelStatement.cs‎

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ public override void ExplicitVisit(CreateExternalModelStatement node)
1717
GenerateSpaceAndIdentifier(CodeGenerationSupporter.Model);
1818
GenerateCreateExternalModelStatementBody(node);
1919
}
20-
protected static Dictionary<ExternalModelTypeOptionKind, string> _externalModelTypeOptionKind = new Dictionary<ExternalModelTypeOptionKind, string>()
20+
protected static Dictionary<ExternalModelTypeOption, string> _externalModelTypeOption = new Dictionary<ExternalModelTypeOption, string>()
2121
{
22-
{ExternalModelTypeOptionKind.Embeddings, CodeGenerationSupporter.Embeddings}
22+
{ExternalModelTypeOption.EMBEDDINGS, CodeGenerationSupporter.Embeddings}
2323
};
2424

2525
protected void GenerateCreateExternalModelStatementBody(CreateExternalModelStatement node)
@@ -54,15 +54,26 @@ protected void GenerateCreateExternalModelStatementBody(CreateExternalModelState
5454
}
5555

5656
// external model Model Type options
57-
if (node.ModelType != null)
57+
if (node.ModelTypeSpecification != null)
5858
{
5959
if (!ifFirst)
6060
{
6161
GenerateSymbol(TSqlTokenType.Comma);
6262
}
6363
ifFirst = false;
6464
NewLine();
65-
GenerateFragmentIfNotNull(node.ModelType);
65+
GenerateFragmentIfNotNull(node.ModelTypeSpecification);
66+
}
67+
else if (node.ModelType != null)
68+
{
69+
if (!ifFirst)
70+
{
71+
GenerateSymbol(TSqlTokenType.Comma);
72+
}
73+
ifFirst = false;
74+
NewLine();
75+
string externalModelTypeOption = GetValueForEnumKey(_externalModelTypeOption, node.ModelType.Value);
76+
GenerateNameEqualsValue(CodeGenerationSupporter.ModelType, externalModelTypeOption);
6677
}
6778

6879
// external model name options
@@ -117,9 +128,9 @@ protected void GenerateCreateExternalModelStatementBody(CreateExternalModelState
117128
GenerateKeyword(TSqlTokenType.RightParenthesis);
118129
}
119130

120-
public override void ExplicitVisit(ExternalModelTypeOption node)
131+
public override void ExplicitVisit(ExternalModelTypeSpecification node)
121132
{
122-
string optionKindString = GetValueForEnumKey(_externalModelTypeOptionKind, node.OptionKind);
133+
string optionKindString = GetValueForEnumKey(_externalModelTypeOption, node.OptionKind);
123134
GenerateNameEqualsValue(CodeGenerationSupporter.ModelType, optionKindString);
124135
}
125136
}

‎Test/SqlDom/Only170SyntaxTests.cs‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -407,18 +407,24 @@ public void TestExternalModelModelTypeVisitor()
407407
Assert.IsNotNull(fragment);
408408

409409
// Collect all visited fragments using a custom visitor
410-
var visitor = new ExternalModelTypeOptionVisitor();
410+
var visitor = new ExternalModelTypeSpecificationVisitor();
411411
fragment.Accept(visitor);
412412

413413
Assert.AreEqual(1, visitor.VisitedOptions.Count);
414-
Assert.AreEqual(ExternalModelTypeOptionKind.Embeddings, visitor.VisitedOptions[0].OptionKind);
414+
Assert.AreEqual(ExternalModelTypeOption.EMBEDDINGS, visitor.VisitedOptions[0].OptionKind);
415+
416+
// Legacy enum member must still be populated for backward compatibility
417+
var createStatement = ((TSqlScript)fragment).Batches[0].Statements[0] as CreateExternalModelStatement;
418+
Assert.IsNotNull(createStatement);
419+
Assert.AreEqual(ExternalModelTypeOption.EMBEDDINGS, createStatement.ModelType);
420+
Assert.IsNotNull(createStatement.ModelTypeSpecification);
415421
}
416422

417-
private class ExternalModelTypeOptionVisitor : TSqlFragmentVisitor
423+
private class ExternalModelTypeSpecificationVisitor : TSqlFragmentVisitor
418424
{
419-
public List<ExternalModelTypeOption> VisitedOptions { get; } = new List<ExternalModelTypeOption>();
425+
public List<ExternalModelTypeSpecification> VisitedOptions { get; } = new List<ExternalModelTypeSpecification>();
420426

421-
public override void Visit(ExternalModelTypeOption node)
427+
public override void Visit(ExternalModelTypeSpecification node)
422428
{
423429
VisitedOptions.Add(node);
424430
base.Visit(node);

0 commit comments

Comments
 (0)