Skip to content

Commit 3783875

Browse files
committed
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 e5910c4 commit 3783875

File tree

17 files changed

+306
-646
lines changed

17 files changed

+306
-646
lines changed

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

+8-28
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

+4-4
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
}
@@ -437,7 +437,7 @@ protected static SqlUserFunctionCall BitNot(SqlExpression operand) =>
437437
SqlDml.RawConcat(
438438
operand,
439439
SqlDml.Native("AS SIGNED"))));
440-
440+
441441

442442
#endregion
443443

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

+17-33
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

+8-18
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

+2-7
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

+5-17
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)

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

+2-7
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

+1-1
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

+29-50
Original file line numberDiff line numberDiff line change
@@ -314,42 +314,31 @@ public override string Translate(SqlJoinMethod method)
314314
};
315315
}
316316

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

355344
static void AppendHint(IOutput output, string hint, ref bool hasHints)
@@ -365,18 +354,8 @@ static void AppendHint(IOutput output, string hint, ref bool hasHints)
365354
}
366355
}
367356

368-
/// <inheritdoc/>
369-
public override void Translate(SqlCompilerContext context, SqlUpdate node, UpdateSection section)
370-
{
371-
switch (section) {
372-
case UpdateSection.Limit:
373-
_ = context.Output.Append("TOP");
374-
break;
375-
default:
376-
base.Translate(context, node, section);
377-
break;
378-
}
379-
}
357+
public override void UpdateLimit(SqlCompilerContext context) =>
358+
context.Output.AppendSpaceIfNecessary().Append("TOP").AppendSpaceIfNecessary();
380359

381360
/// <inheritdoc/>
382361
public override void Translate(SqlCompilerContext context, SqlDelete node, DeleteSection section)
@@ -677,19 +656,19 @@ protected virtual string GetCurentNameOfDefaultConstraintScript()
677656
{
678657
return @"DECLARE @{0} VARCHAR(256)
679658
SELECT @{0} = {1}.sys.default_constraints.name
680-
FROM
659+
FROM
681660
{1}.sys.all_columns
682661
INNER JOIN
683662
{1}.sys.tables
684663
ON all_columns.object_id = tables.object_id
685-
INNER JOIN
664+
INNER JOIN
686665
{1}.sys.schemas
687-
ON tables.schema_id = schemas.schema_id
666+
ON tables.schema_id = schemas.schema_id
688667
INNER JOIN
689668
{1}.sys.default_constraints
690669
ON all_columns.default_object_id = default_constraints.object_id
691670
692-
WHERE
671+
WHERE
693672
schemas.name = '{2}'
694673
AND tables.name = '{3}'
695674
AND all_columns.name = '{4}'";

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

+4-6
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)