Skip to content

Commit 45d9e38

Browse files
authored
Optimization: Dispatch Translator by virtual functions instead of switch statements (#118)
* Optimization: Dispatch Translator by virtual functions instead of switch statements * AppendSpacePrefixed() helper * Refactor ColumnSection * virtual JoinCondition() * Eliminate IfSection * Eliminate InsertSection * LikeSection * BetweenSection * FetchSection * WhileSection * SqlOrder * UpdateSection
1 parent 5aa9ba9 commit 45d9e38

File tree

17 files changed

+305
-651
lines changed

17 files changed

+305
-651
lines changed

Orm/Xtensive.Orm.Firebird/Sql.Drivers.Firebird/v2_5/Translator.cs

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -231,34 +231,14 @@ public override void Translate(IOutput output, SqlDatePart datePart)
231231
}
232232
}
233233

234-
/// <inheritdoc/>
235-
public override void Translate(SqlCompilerContext context, SqlSelect node, SelectSection section)
236-
{
237-
switch (section) {
238-
case SelectSection.Limit:
239-
_ = context.Output.Append("FIRST");
240-
break;
241-
case SelectSection.Offset:
242-
_ = context.Output.Append("SKIP");
243-
break;
244-
default:
245-
base.Translate(context, node, section);
246-
break;
247-
}
248-
}
234+
public override void SelectLimit(SqlCompilerContext context, SqlSelect node) =>
235+
context.Output.AppendSpacePrefixed("FIRST ");
249236

250-
/// <inheritdoc/>
251-
public override void Translate(SqlCompilerContext context, SqlUpdate node, UpdateSection section)
252-
{
253-
switch (section) {
254-
case UpdateSection.Limit:
255-
_ = context.Output.Append("ROWS");
256-
break;
257-
default:
258-
base.Translate(context, node, section);
259-
break;
260-
}
261-
}
237+
public override void SelectOffset(SqlCompilerContext context, SqlSelect node) =>
238+
context.Output.AppendSpacePrefixed("SKIP ");
239+
240+
public override void UpdateLimit(SqlCompilerContext context) =>
241+
context.Output.AppendSpaceIfNecessary().Append("ROWS").AppendSpaceIfNecessary();
262242

263243
/// <inheritdoc />
264244
public override void Translate(SqlCompilerContext context, SqlDelete node, DeleteSection section)
@@ -380,4 +360,4 @@ public Translator(SqlDriver driver)
380360
DoubleFormatString = $"{base.DoubleFormatString}e0";
381361
}
382362
}
383-
}
363+
}

Orm/Xtensive.Orm.MySql/Sql.Drivers.MySql/v5_0/Compiler.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,15 +258,15 @@ public override void Visit(SqlPlaceholder node)
258258
protected override void VisitSelectLimitOffset(SqlSelect node)
259259
{
260260
if (node.Limit is not null) {
261-
AppendTranslated(node, SelectSection.Limit);
261+
translator.SelectLimit(context, node);
262262
node.Limit.AcceptVisitor(this);
263263
}
264264
if (node.Offset is not null) {
265265
if (node.Limit is null) {
266-
AppendTranslated(node, SelectSection.Limit);
266+
translator.SelectLimit(context, node);
267267
_ = context.Output.Append(" 18446744073709551615 "); // magic number from http://dev.mysql.com/doc/refman/5.0/en/select.html
268268
}
269-
AppendTranslated(node, SelectSection.Offset);
269+
translator.SelectOffset(context, node);
270270
node.Offset.AcceptVisitor(this);
271271
}
272272
}

Orm/Xtensive.Orm.MySql/Sql.Drivers.MySql/v5_0/Translator.cs

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -63,34 +63,26 @@ protected override void TranslateChar(IOutput output, char ch)
6363
}
6464
}
6565

66-
/// <inheritdoc/>
67-
public override void Translate(SqlCompilerContext context, SqlSelect node, SelectSection section)
66+
public override void SelectHintsEntry(SqlCompilerContext context, SqlSelect node) { }
67+
68+
public override void SelectHintsExit(SqlCompilerContext context, SqlSelect node)
6869
{
69-
switch (section) {
70-
case SelectSection.HintsEntry:
71-
break;
72-
case SelectSection.HintsExit:
73-
if (node.Hints.Count == 0) {
74-
break;
70+
if (node.Hints.Count != 0) {
71+
var hints = new List<string>(node.Hints.Count);
72+
foreach (var hint in node.Hints) {
73+
if (hint is SqlNativeHint sqlNativeHint) {
74+
hints.Add(QuoteIdentifier(sqlNativeHint.HintText));
7575
}
76-
var hints = new List<string>(node.Hints.Count);
77-
foreach (var hint in node.Hints) {
78-
if (hint is SqlNativeHint sqlNativeHint) {
79-
hints.Add(QuoteIdentifier(sqlNativeHint.HintText));
80-
}
81-
}
82-
if (hints.Count > 0) {
83-
_ = context.Output.Append("USE INDEX (")
84-
.Append(string.Join(", ", hints))
85-
.Append(")");
86-
}
87-
break;
88-
default:
89-
base.Translate(context, node, section);
90-
break;
76+
}
77+
if (hints.Count > 0) {
78+
_ = context.Output.Append("USE INDEX (")
79+
.Append(string.Join(", ", hints))
80+
.Append(")");
81+
}
9182
}
9283
}
9384

85+
9486
/// <inheritdoc/>
9587
public override void Translate(IOutput output, SqlFunctionType type)
9688
{
@@ -356,16 +348,8 @@ public override void Translate(SqlCompilerContext context, SqlAlterTable node, A
356348
}
357349
}
358350

359-
/// <inheritdoc/>
360-
public override void Translate(SqlCompilerContext context, SqlInsert node, InsertSection section)
361-
{
362-
if (section == InsertSection.DefaultValues) {
363-
_ = context.Output.Append("() VALUES ()");
364-
}
365-
else {
366-
base.Translate(context, node, section);
367-
}
368-
}
351+
public override void InsertDefaultValues(SqlCompilerContext context) =>
352+
context.Output.AppendSpaceIfNecessary().AppendOpeningPunctuation("() VALUES ()");
369353

370354
/// <inheritdoc/>
371355
public override void Translate(SqlCompilerContext context, SqlBreak node)

Orm/Xtensive.Orm.Oracle/Sql.Drivers.Oracle/v09/Translator.cs

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,24 +70,14 @@ public override void TranslateString(IOutput output, string str)
7070
base.TranslateString(output, str);
7171
}
7272

73-
/// <inheritdoc/>
74-
public override void Translate(SqlCompilerContext context, SqlSelect node, SelectSection section)
75-
{
76-
switch (section) {
77-
case SelectSection.HintsEntry:
78-
_ = context.Output.Append("/*+");
79-
break;
80-
case SelectSection.HintsExit:
81-
_ = context.Output.Append("*/");
82-
break;
83-
case SelectSection.Limit:
84-
case SelectSection.Offset:
85-
throw new NotSupportedException();
86-
default:
87-
base.Translate(context, node, section);
88-
break;
89-
}
90-
}
73+
public override void SelectLimit(SqlCompilerContext context, SqlSelect node) => throw new NotSupportedException();
74+
public override void SelectOffset(SqlCompilerContext context, SqlSelect node) => throw new NotSupportedException();
75+
76+
public override void SelectHintsEntry(SqlCompilerContext context, SqlSelect node) =>
77+
context.Output.AppendSpacePrefixed("/*+ ");
78+
79+
public override void SelectHintsExit(SqlCompilerContext context, SqlSelect node) =>
80+
context.Output.AppendSpacePrefixed("*/ ");
9181

9282
/// <inheritdoc/>
9383
public override string Translate(SqlJoinMethod method)

Orm/Xtensive.Orm.Oracle/Sql.Drivers.Oracle/v11/Translator.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,8 @@ namespace Xtensive.Sql.Drivers.Oracle.v11
1313
{
1414
internal class Translator : v10.Translator
1515
{
16-
/// <inheritdoc/>
17-
public override void Translate(SqlCompilerContext context, SqlOrder node, NodeSection section)
18-
{
19-
if (section == NodeSection.Exit) {
20-
_ = context.Output.Append(node.Ascending ? "ASC NULLS FIRST" : "DESC NULLS LAST");
21-
}
22-
}
16+
public override void OrderExit(SqlCompilerContext context, SqlOrder node) =>
17+
context.Output.Append(node.Ascending ? "ASC NULLS FIRST" : "DESC NULLS LAST");
2318

2419
/// <inheritdoc/>
2520
public override string Translate(SqlValueType type)

Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/v8_0/Translator.cs

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -453,23 +453,11 @@ public override void Translate(SqlCompilerContext context, SqlDeclareCursor node
453453
}
454454
}
455455

456-
/// <inheritdoc/>
457-
public override void Translate(SqlCompilerContext context, SqlFetch node, FetchSection section)
458-
{
459-
switch (section) {
460-
case FetchSection.Entry:
461-
_ = context.Output.Append("FETCH ").Append(node.Option.ToString().ToUpper());
462-
return;
463-
case FetchSection.Targets:
464-
var output = context.Output;
465-
_ = output.Append("FROM ");
466-
TranslateIdentifier(output, node.Cursor.Name);
467-
return;
468-
case FetchSection.Exit:
469-
break;
470-
}
471-
base.Translate(context, node, section);
472-
}
456+
public override void FetchEntry(SqlCompilerContext context, SqlFetch node) =>
457+
context.Output.Append("FETCH ").Append(node.Option.ToString().ToUpper());
458+
459+
public override void FetchTarget(SqlCompilerContext context, SqlFetch node) =>
460+
TranslateIdentifier(context.Output.AppendSpaceIfNecessary().Append("FROM "), node.Cursor.Name);
473461

474462
/// <inheritdoc/>
475463
public override void Translate(SqlCompilerContext context, SqlOpenCursor node)
@@ -962,4 +950,4 @@ public Translator(SqlDriver driver)
962950
DoubleFormatString = base.DoubleFormatString + "'::float8'";
963951
}
964952
}
965-
}
953+
}

Orm/Xtensive.Orm.PostgreSql/Sql.Drivers.PostgreSql/v8_3/Translator.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,8 @@ public override void Translate(SqlCompilerContext context, SqlCreateIndex node,
4444
}
4545
}
4646

47-
/// <inheritdoc/>
48-
public override void Translate(SqlCompilerContext context, SqlOrder node, NodeSection section)
49-
{
50-
if (section == NodeSection.Exit) {
51-
_ = context.Output.Append(node.Ascending ? "ASC NULLS FIRST" : "DESC NULLS LAST");
52-
}
53-
}
47+
public override void OrderExit(SqlCompilerContext context, SqlOrder node) =>
48+
context.Output.Append(node.Ascending ? "ASC NULLS FIRST" : "DESC NULLS LAST");
5449

5550
internal protected string GetFulltextVector(SqlCompilerContext context, FullTextIndex index)
5651
{

Orm/Xtensive.Orm.SqlServer/Sql.Drivers.SqlServer/v09/Compiler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ protected override void VisitUpdateLimit(SqlUpdate node)
8383
throw new NotSupportedException(Strings.ExStorageDoesNotSupportLimitationOfRowCountToUpdate);
8484
}
8585

86-
AppendTranslated(node, UpdateSection.Limit);
86+
translator.UpdateLimit(context);
8787
_ = context.Output.AppendOpeningPunctuation("(");
8888
node.Limit.AcceptVisitor(this);
8989
_ = context.Output.Append(")");

Orm/Xtensive.Orm.SqlServer/Sql.Drivers.SqlServer/v09/Translator.cs

Lines changed: 25 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -318,45 +318,32 @@ public override string Translate(SqlJoinMethod method)
318318
};
319319
}
320320

321-
/// <inheritdoc/>
322-
public override void Translate(SqlCompilerContext context, SqlSelect node, SelectSection section)
321+
public override void SelectLimit(SqlCompilerContext context, SqlSelect node) =>
322+
context.Output.AppendSpacePrefixed("TOP ");
323+
324+
public override void SelectOffset(SqlCompilerContext context, SqlSelect node) => throw new NotSupportedException();
325+
326+
public override void SelectExit(SqlCompilerContext context, SqlSelect node)
323327
{
324328
var output = context.Output;
325-
switch (section) {
326-
case SelectSection.Entry:
327-
base.Translate(context, node, section);
328-
break;
329-
case SelectSection.Limit:
330-
_ = output.Append("TOP");
331-
break;
332-
case SelectSection.Offset:
333-
throw new NotSupportedException();
334-
case SelectSection.Exit:
335-
var hasHints = false;
336-
foreach (var hint in node.Hints) {
337-
switch (hint) {
338-
case SqlForceJoinOrderHint:
339-
AppendHint(output, "FORCE ORDER", ref hasHints);
340-
break;
341-
case SqlFastFirstRowsHint sqlFastFirstRowsHint:
342-
AppendHint(output, "FAST ", ref hasHints);
343-
_ = output.Append(sqlFastFirstRowsHint.Amount);
344-
break;
345-
case SqlNativeHint sqlNativeHint:
346-
AppendHint(output, sqlNativeHint.HintText, ref hasHints);
347-
break;
348-
}
349-
}
350-
if (hasHints) {
351-
_ = output.Append(")");
352-
}
353-
break;
354-
default:
355-
base.Translate(context, node, section);
356-
break;
329+
var hasHints = false;
330+
foreach (var hint in node.Hints) {
331+
switch (hint) {
332+
case SqlForceJoinOrderHint:
333+
AppendHint(output, "FORCE ORDER", ref hasHints);
334+
break;
335+
case SqlFastFirstRowsHint sqlFastFirstRowsHint:
336+
AppendHint(output, "FAST ", ref hasHints);
337+
_ = output.Append(sqlFastFirstRowsHint.Amount);
338+
break;
339+
case SqlNativeHint sqlNativeHint:
340+
AppendHint(output, sqlNativeHint.HintText, ref hasHints);
341+
break;
342+
}
343+
}
344+
if (hasHints) {
345+
_ = output.Append(")");
357346
}
358-
359-
/// <inheritdoc/>
360347

361348
static void AppendHint(IOutput output, string hint, ref bool hasHints)
362349
{
@@ -371,17 +358,8 @@ static void AppendHint(IOutput output, string hint, ref bool hasHints)
371358
}
372359
}
373360

374-
public override void Translate(SqlCompilerContext context, SqlUpdate node, UpdateSection section)
375-
{
376-
switch (section) {
377-
case UpdateSection.Limit:
378-
_ = context.Output.Append("TOP");
379-
break;
380-
default:
381-
base.Translate(context, node, section);
382-
break;
383-
}
384-
}
361+
public override void UpdateLimit(SqlCompilerContext context) =>
362+
context.Output.AppendSpaceIfNecessary().Append("TOP").AppendSpaceIfNecessary();
385363

386364
/// <inheritdoc/>
387365
public override void Translate(SqlCompilerContext context, SqlDelete node, DeleteSection section)

Orm/Xtensive.Orm.SqlServer/Sql.Drivers.SqlServer/v11/Compiler.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ protected override void VisitSelectLimitOffset(SqlSelect node)
2626
return; // Nothing to process.
2727
}
2828

29-
AppendTranslated(node, SelectSection.Offset);
29+
translator.SelectOffset(context, node);
3030

3131
if (node.HasOffset) {
3232
node.Offset.AcceptVisitor(this);
@@ -35,14 +35,12 @@ protected override void VisitSelectLimitOffset(SqlSelect node)
3535
_ = context.Output.Append("0");
3636
}
3737

38-
AppendSpaceIfNecessary();
39-
translator.Translate(context, node, SelectSection.OffsetEnd);
38+
translator.SelectOffsetEnd(context, node);
4039

4140
if (node.HasLimit) {
42-
AppendTranslated(node, SelectSection.Limit);
41+
translator.SelectLimit(context, node);
4342
node.Limit.AcceptVisitor(this);
44-
AppendSpaceIfNecessary();
45-
translator.Translate(context, node, SelectSection.LimitEnd);
43+
translator.SelectLimitEnd(context, node);
4644
}
4745
}
4846

0 commit comments

Comments
 (0)