class BetterCteClause : AbstractFrom {
public string Expression { get; set; }
public object[] Bindings { set; get; }
public override AbstractClause Clone()
BetterCteClause betterCte = new BetterCteClause();
betterCte.Engine = this.Engine;
betterCte.Alias = this.Alias;
betterCte.Expression = this.Expression;
betterCte.Bindings = this.Bindings;
betterCte.Component = this.Component;
return (AbstractClause) betterCte;
class BetterPostgresCompiler : PostgresCompiler {
public BetterPostgresCompiler() : base() {}
public override SqlResult CompileCte(AbstractFrom cte) {
case BetterCteClause ourCteClause:
var result = new SqlResult();
result.Bindings.AddRange(ourCteClause.Bindings);
result.RawSql = this.WrapValue(ourCteClause.Alias) + " AS NOT MATERIALIZED (" + this.WrapIdentifiers(ourCteClause.Expression) + ")";
return base.CompileCte(cte);
public override SqlResult Compile(Query query) {
return base.Compile(query);
class BetterQuery : Query {
public BetterQuery BetterWithRaw(string alias, string expression, object[] bindings = null) {
var clause = new BetterCteClause();
clause.Expression = expression;
clause.Bindings = bindings ?? [];
this.AddComponent("cte", clause);
public static void Main()
var compiler = new BetterPostgresCompiler();
var query1 = new BetterQuery();
query1.BetterWithRaw("amd", "select 1");
var compiled1 = compiler.Compile(query1);
Console.WriteLine(compiled1.ToString());