Skip to content

Commit

Permalink
Add MS SQL Server Table hint
Browse files Browse the repository at this point in the history
  • Loading branch information
hiro80 committed May 2, 2019
1 parent 7e0c943 commit 5832fac
Show file tree
Hide file tree
Showing 17 changed files with 4,398 additions and 4,067 deletions.
11 changes: 11 additions & 0 deletions MiniSqlParser/Enums/MsSqlHint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace MiniSqlParser
{
public enum MsSqlHint
{
None,
NoLock,
ReadCommitted,
RepeatableRead,
Serializable
}
}
33 changes: 25 additions & 8 deletions MiniSqlParser/FromSources/Table.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ public FromSourceType Type {
public Identifier IndexName { get; private set; }
public bool HasNotIndexed { get; private set; }

// MS SQL Serverでのテーブルヒント
public MsSqlHint MsSqlHint { get; private set; }

public Table Clone() {
var ret = new Table(_serverName
, _dataBaseName
Expand All @@ -144,6 +147,7 @@ public Table Clone() {
, this.IndexSchemaName
, this.IndexName
, this.HasNotIndexed
, this.MsSqlHint
, this.Comments.Clone());
ret.Attachment = this.Attachment;
return ret;
Expand All @@ -165,7 +169,9 @@ internal Table(Identifier serverName
, null
, null
, null
, false,comments){
, false
, MsSqlHint.None
, comments){
}

internal Table(Identifier serverName
Expand All @@ -188,6 +194,7 @@ internal Table(Identifier serverName
, null
, null
, false
, MsSqlHint.None
, comments) {
}

Expand All @@ -203,6 +210,7 @@ internal Table(Identifier serverName
, Identifier indexSchemaName
, Identifier indexName
, bool hasNotIndexed
, MsSqlHint msSqlHint
, Comments comments) {
_serverName = serverName;
_dataBaseName = databaseName;
Expand All @@ -216,6 +224,7 @@ internal Table(Identifier serverName
this.IndexSchemaName = indexSchemaName;
this.IndexName = indexName;
this.HasNotIndexed = hasNotIndexed;
this.MsSqlHint = msSqlHint;
this.Comments = comments;
}

Expand All @@ -230,7 +239,8 @@ public Table(Identifier name)
, null
, null
, null
, false) {
, false
, MsSqlHint.None) {
}

public Table(Identifier name
Expand All @@ -246,7 +256,8 @@ public Table(Identifier name
, null
, null
, null
, false) {
, false
, MsSqlHint.None) {
}

public Table(Identifier schemaName
Expand All @@ -261,7 +272,8 @@ public Table(Identifier schemaName
, null
, null
, null
, false) {
, false
, MsSqlHint.None) {
}

public Table(Identifier serverName
Expand All @@ -278,7 +290,8 @@ public Table(Identifier serverName
, null
, null
, null
, false) {
, false
, MsSqlHint.None) {
}

public Table(Identifier serverName
Expand All @@ -297,7 +310,8 @@ public Table(Identifier serverName
, null
, null
, null
, false) {
, false
, MsSqlHint.None) {
}

public Table(Identifier serverName
Expand All @@ -310,7 +324,8 @@ public Table(Identifier serverName
, Identifier indexDatabaseName
, Identifier indexSchemaName
, Identifier indexName
, bool hasNotIndexed) {
, bool hasNotIndexed
, MsSqlHint msSqlHint) {
_serverName = serverName;
_dataBaseName = databaseName;
_schemaName = schemaName;
Expand All @@ -322,8 +337,10 @@ public Table(Identifier serverName
this.IndexSchemaName = indexSchemaName;
this.IndexName = indexName;
this.HasNotIndexed = hasNotIndexed;
this.MsSqlHint = msSqlHint;

// コメントスロット数を計算する
var h = CountTrue(msSqlHint != MsSqlHint.None) * 4;
var n = CountTrue(!string.IsNullOrEmpty(indexName)) * 3;
var m = CountTrue(!string.IsNullOrEmpty(serverName)
, !string.IsNullOrEmpty(databaseName)
Expand All @@ -335,7 +352,7 @@ public Table(Identifier serverName
var l = CountTrue(HasAs
, !string.IsNullOrEmpty(aliasName));

this.Comments = new Comments(n + m + l + 1);
this.Comments = new Comments(h + n + m + l + 1);
}

protected override void AcceptImp(IVisitor visitor) {
Expand Down
1 change: 1 addition & 0 deletions MiniSqlParser/MiniSqlParser.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
<Compile Include="Assignment.cs" />
<Compile Include="Assignments.cs" />
<Compile Include="BestCaseDictionary.cs" />
<Compile Include="Enums\MsSqlHint.cs" />
<Compile Include="Parser\MiniSqlParserBaseListener.cs" />
<Compile Include="Parser\MiniSqlParserLexer.cs" />
<Compile Include="Parser\MiniSqlParserListener.cs" />
Expand Down
133 changes: 76 additions & 57 deletions MiniSqlParser/Parser/MakeASTListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1124,85 +1124,104 @@ public override void ExitAliased_table_name(MiniSqlParserParser.Aliased_table_na
, comments));
}

public override void ExitIndexed_table_name(MiniSqlParserParser.Indexed_table_nameContext context) {
public override void ExitHinted_table_name(MiniSqlParserParser.Hinted_table_nameContext context) {
if(context.table_hint() == null) {
// table_hintが存在しない場合はなにもしない
return;
}

var tableNode = (Table)_stack.Pop();
var comments = tableNode.Comments;
comments.AddRange(this.GetComments(context));

Identifier indexServerName = null;
Identifier indexDatabaseName = null;
Identifier indexSchemaName = null;
Identifier indexName = null;
bool hasNotIndexed = false;
if(context.K_NOT() != null) {
hasNotIndexed = true;
} else if(context.K_INDEXED() != null) {
comments.AddRange(this.GetComments(context.index_name().qualified_schema_name()));
comments.AddRange(this.GetComments(context.index_name()));
if(context.index_name().qualified_schema_name() != null) {
indexServerName = this.GetIdentifier(context.index_name().qualified_schema_name().s);
indexDatabaseName = this.GetIdentifier(context.index_name().qualified_schema_name().d);
indexSchemaName = this.GetIdentifier(context.index_name().qualified_schema_name().n);
}
indexName = this.GetIdentifier(context.index_name().identifier());
}
comments.AddRange(this.GetComments(context.table_hint()));

// コメントでテーブル別名の指定があれば取得する
var implicitAliasName = this.GetTableAliasNameFromDocComment(context);

_stack.Push(new Table(tableNode.ServerName
, tableNode.DataBaseName
, tableNode.SchemaName
, tableNode.Name
, false
, null
, implicitAliasName
, indexServerName
, indexDatabaseName
, indexSchemaName
, indexName
, hasNotIndexed
, comments));
var hinted_table = this.CreateHintedTable(context.table_hint()
, tableNode
, implicitAliasName
, comments);
_stack.Push(hinted_table);
}

public override void ExitIndexed_aliased_table_name(MiniSqlParserParser.Indexed_aliased_table_nameContext context) {
public override void ExitHinted_aliased_table_name(MiniSqlParserParser.Hinted_aliased_table_nameContext context) {
if(context.table_hint() == null) {
// table_hintが存在しない場合はなにもしない
return;
}

var tableNode = (Table)_stack.Pop();
var comments = tableNode.Comments;
comments.AddRange(this.GetComments(context));
comments.AddRange(this.GetComments(context.table_hint()));

var hinted_table = this.CreateHintedTable(context.table_hint()
, tableNode
, tableNode.ImplicitAliasName
, comments);
_stack.Push(hinted_table);
}

private Table CreateHintedTable(MiniSqlParserParser.Table_hintContext table_hintContext
, Table tableNode
, string implicitAliasName
, Comments comments) {
Identifier indexServerName = null;
Identifier indexDatabaseName = null;
Identifier indexSchemaName = null;
Identifier indexName = null;
bool hasNotIndexed = false;
if(context.K_NOT() != null) {

if(table_hintContext.K_NOT() != null) {
hasNotIndexed = true;
} else if(context.K_INDEXED() != null) {
comments.AddRange(this.GetComments(context.index_name().qualified_schema_name()));
comments.AddRange(this.GetComments(context.index_name()));
if(context.index_name().qualified_schema_name() != null) {
indexServerName = this.GetIdentifier(context.index_name().qualified_schema_name().s);
indexDatabaseName = this.GetIdentifier(context.index_name().qualified_schema_name().d);
indexSchemaName = this.GetIdentifier(context.index_name().qualified_schema_name().n);
} else if(table_hintContext.K_INDEXED() != null) {
comments.AddRange(this.GetComments(table_hintContext.index_name().qualified_schema_name()));
comments.AddRange(this.GetComments(table_hintContext.index_name()));
if(table_hintContext.index_name().qualified_schema_name() != null) {
indexServerName = this.GetIdentifier(table_hintContext.index_name().qualified_schema_name().s);
indexDatabaseName = this.GetIdentifier(table_hintContext.index_name().qualified_schema_name().d);
indexSchemaName = this.GetIdentifier(table_hintContext.index_name().qualified_schema_name().n);
}
indexName = this.GetIdentifier(context.index_name().identifier());
}
indexName = this.GetIdentifier(table_hintContext.index_name().identifier());
}
var msSqlHint = this.ConvToMsSqlHint(table_hintContext.h);

return new Table(tableNode.ServerName
, tableNode.DataBaseName
, tableNode.SchemaName
, tableNode.Name
, tableNode.HasAs
, tableNode.AliasName
, implicitAliasName
, indexServerName
, indexDatabaseName
, indexSchemaName
, indexName
, hasNotIndexed
, msSqlHint
, comments);
}

_stack.Push(new Table(tableNode.ServerName
, tableNode.DataBaseName
, tableNode.SchemaName
, tableNode.Name
, tableNode.HasAs
, tableNode.AliasName
, tableNode.ImplicitAliasName
, indexServerName
, indexDatabaseName
, indexSchemaName
, indexName
, hasNotIndexed
, comments));
private MsSqlHint ConvToMsSqlHint(IToken msSqlHint) {
if(msSqlHint == null) {
return MsSqlHint.None;
}
var hintType = msSqlHint.Type;
MsSqlHint hint = MsSqlHint.None;
if(hintType == MiniSqlParserLexer.K_NOLOCK) {
hint = MsSqlHint.NoLock;
} else if(hintType == MiniSqlParserLexer.K_READCOMMITTED) {
hint = MsSqlHint.ReadCommitted;
} else if(hintType == MiniSqlParserLexer.K_REPEATABLEREAD) {
hint = MsSqlHint.RepeatableRead;
} else if(hintType == MiniSqlParserLexer.K_SERIALIZABLE) {
hint = MsSqlHint.Serializable;
} else {
throw new CannotBuildASTException("Undifined Ms SQL Hint is used");
}
return hint;
}

}

}
2 changes: 1 addition & 1 deletion MiniSqlParser/Parser/MakeASTListener_Util.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ private string GetTableAliasNameFromDocComment(MiniSqlParserParser.Aliased_table
return this.GetTableAliasNameFromDocComment(context.table_name());
}

private string GetTableAliasNameFromDocComment(MiniSqlParserParser.Indexed_table_nameContext context) {
private string GetTableAliasNameFromDocComment(MiniSqlParserParser.Hinted_table_nameContext context) {
return this.GetTableAliasNameFromDocComment(context.table_name());
}

Expand Down
Loading

0 comments on commit 5832fac

Please sign in to comment.