Skip to content

Refactor compiler to use the Visitor patterns - #787

Open
ahmad-moussawi wants to merge 2 commits into
mainfrom
refactor_compiler
Open

ahmad-moussawi wants to merge 2 commits into
mainfrom
refactor_compiler

Conversation

@ahmad-moussawi

Copy link
Copy Markdown
Contributor

Old SqlResult was playing multiple roles, as a compilation context, and as a execution result.

create a new compilation context CompileContext that act as the context when compiling the query, and keep SqlResult for the final result only.

Refactor the compiler to use a light weight Visitor pattern instead of the old string concatenation, leading to faster and cleaner compilation.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The visitor implementation has SQL-generation regressions for empty conditions, random ordering, and outer-variable resolution.

4 open findings
What changed in this PR

Refactors SQL compilation around a dedicated visitor-based CompileContext, leaving SqlResult as the final execution result.

Changes:

  • Replaces string-returning compiler methods with visitor methods.
  • Migrates dialect-specific pagination and condition compilation.
  • Updates limit tests and adds binding-order coverage.
File Description
QueryBuilder/​SqlResult.cs Simplifies result construction defaults.
QueryBuilder/​Compilers/​CompileContext.cs Adds compilation state and query-stack handling.
QueryBuilder/​Compilers/​Compiler.cs Implements core visitor-based compilation.
QueryBuilder/​Compilers/​Compiler.Conditions.cs Implements condition visitors.
QueryBuilder/​Compilers/​SqlServerCompiler.cs Migrates SQL Server compilation.
QueryBuilder/​Compilers/​SqliteCompiler.cs Migrates SQLite compilation.
QueryBuilder/​Compilers/​PostgresCompiler.cs Migrates PostgreSQL compilation.
QueryBuilder/​Compilers/​OracleCompiler.cs Migrates Oracle compilation.
QueryBuilder/​Compilers/​MySqlCompiler.cs Migrates MySQL pagination.
QueryBuilder/​Compilers/​FirebirdCompiler.cs Migrates Firebird compilation.
QueryBuilder.Tests/​SqlServer/​SqlServerLimitTests.cs Uses CompileContext.
QueryBuilder.Tests/​SqlServer/​SqlServerLegacyLimitTests.cs Uses CompileContext.
QueryBuilder.Tests/​Sqlite/​SqliteLimitTests.cs Uses CompileContext.
QueryBuilder.Tests/​PostgreSql/​PostgreSqlLimitTests.cs Uses CompileContext.
QueryBuilder.Tests/​Oracle/​OracleLimitTests.cs Uses CompileContext.
QueryBuilder.Tests/​Oracle/​OracleLegacyLimitTests.cs Uses CompileContext.
QueryBuilder.Tests/​MySql/​MySqlLimitTests.cs Uses CompileContext.
QueryBuilder.Tests/​Firebird/​FirebirdLimitTests.cs Uses CompileContext.
QueryBuilder.Tests/​GeneralTests.cs Adds pagination binding-order tests.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

}

return string.Join(" ", result);
if (ctx.Buffer.Length > 0 && ctx.Buffer[ctx.Buffer.Length - 1] == ' ')
Comment on lines +278 to +282
ctx.Write(Wrap(item.Column));

if (!item.Values.Any())
{
return item.IsNot ? $"1 = 1 /* NOT IN [empty list] */" : "1 = 0 /* IN [empty list] */";
ctx.Write(item.IsNot ? " 1 = 1 /* NOT IN [empty list] */" : " 1 = 0 /* IN [empty list] */");
alias = string.IsNullOrEmpty(alias) ? "" : $" {ColumnAsKeyword}{alias}";

combinedQueries.Add(WrapIdentifiers(combineRawClause.Expression));
var filterCtx = new CompileContext(ctx.CurrentQuery, parameterPlaceholder, EscapeCharacter);
Comment on lines +761 to +764
else if (x is OrderBy orderBy)
{
var direction = orderBy.Ascending ? "" : " DESC";
ctx.Write(Wrap(orderBy.Column)).Write(direction);

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants