<commit_before>require 'spec_helper'

describe Generator::Relation::Unary, '#visit_veritas_algebra_projection' do
  subject { object.visit_veritas_algebra_projection(projection) }

  let(:relation_name) { 'users'                                          }
  let(:id)            { Attribute::Integer.new(:id)                      }
  let(:name)          { Attribute::String.new(:name)                     }
  let(:age)           { Attribute::Integer.new(:age, :required => false) }
  let(:header)        { [ id, name, age ]                                }
  let(:body)          { [ [ 1, '<NAME>', 35 ] ].each                   }
  let(:base_relation) { BaseRelation.new(relation_name, header, body)    }
  let(:projection)    { operand.project([ :id, :name ])                  }
  let(:object)        { described_class.new                              }

  context 'when the operand is a base relation' do
    let(:operand) { base_relation }

    it_should_behave_like 'a generated SQL SELECT query'

    its(:to_s)     { should eql('SELECT DISTINCT "id", "name" FROM "users"') }
    its(:to_inner) { should eql('SELECT DISTINCT "id", "name" FROM "users"') }
  end

  context 'when the operand is a projection' do
    let(:operand) { base_relation.project([ :id, :name ]) }

    it_should_behave_like 'a generated SQL SELECT query'

    its(:to_s)     { should eql('SELECT DISTINCT "id", "name" FROM "users"') }
    its(:to_inner) { should eql('SELECT DISTINCT "id", "name" FROM "users"') }
  end

  context 'when the operand is a rename' do
    context 'when the projection includes the renamed column' do
      let(:operand)    { base_relation.rename(:id => :user_id) }
      let(:projection) { operand.project([ :user_id, :name ])  }

      it_should_behave_like 'a generated SQL SELECT query'

      its(:to_s)     { pending { should eql('SELECT DISTINCT "id" AS "user_id", "name" FROM "users"') } }
      its(:to_inner) { pending { should eql('SELECT DISTINCT "id" AS "user_id", "name" FROM "users"') } }
    end

    context 'when the projection does not include the renamed column' do
      let(:operand)    { base_relation.rename(:id => :user_id) }
      let(:projection) { operand.project([ :name, :age ])  }

      it_should_behave_like 'a generated SQL SELECT query'

      its(:to_s)     { pending { should eql('SELECT DISTINCT "name", "age" FROM "users" AS "users"') } }
      its(:to_inner) { pending { should eql('SELECT DISTINCT "name", "age" FROM "users" AS "users"') } }
    end
  end

  context 'when the operand is a restriction' do
    let(:operand) { base_relation.restrict { |r| r[:id].eq(1) } }

    it_should_behave_like 'a generated SQL SELECT query'

    its(:to_s)     { should eql('SELECT DISTINCT "id", "name" FROM "users" WHERE "id" = 1') }
    its(:to_inner) { should eql('SELECT DISTINCT "id", "name" FROM "users" WHERE "id" = 1') }
  end

  context 'when the operand is ordered' do
    let(:operand) { base_relation.order }

    it_should_behave_like 'a generated SQL SELECT query'

    its(:to_s)     { should eql('SELECT DISTINCT "id", "name" FROM (SELECT * FROM "users" ORDER BY "id", "name", "age") AS "users"') }
    its(:to_inner) { should eql('SELECT DISTINCT "id", "name" FROM (SELECT * FROM "users" ORDER BY "id", "name", "age") AS "users"') }
  end

  context 'when the operand is reversed' do
    let(:operand) { base_relation.order.reverse }
<commit_msg>Do not collapse rename inside a projection when generating a query<commit_after>require 'spec_helper'

describe Generator::Relation::Unary, '#visit_veritas_algebra_projection' do
  subject { object.visit_veritas_algebra_projection(projection) }

  let(:relation_name) { 'users'                                          }
  let(:id)            { Attribute::Integer.new(:id)                      }
  let(:name)          { Attribute::String.new(:name)                     }
  let(:age)           { Attribute::Integer.new(:age, :required => false) }
  let(:header)        { [ id, name, age ]                                }
  let(:body)          { [ [ 1, '<NAME>', 35 ] ].each                   }
  let(:base_relation) { BaseRelation.new(relation_name, header, body)    }
  let(:projection)    { operand.project([ :id, :name ])                  }
  let(:object)        { described_class.new                              }

  context 'when the operand is a base relation' do
    let(:operand) { base_relation }

    it_should_behave_like 'a generated SQL SELECT query'

    its(:to_s)     { should eql('SELECT DISTINCT "id", "name" FROM "users"') }
    its(:to_inner) { should eql('SELECT DISTINCT "id", "name" FROM "users"') }
  end

  context 'when the operand is a projection' do
    let(:operand) { base_relation.project([ :id, :name ]) }

    it_should_behave_like 'a generated SQL SELECT query'

    its(:to_s)     { should eql('SELECT DISTINCT "id", "name" FROM "users"') }
    its(:to_inner) { should eql('SELECT DISTINCT "id", "name" FROM "users"') }
  end

  context 'when the operand is a rename' do
    context 'when the projection includes the renamed column' do
      let(:operand)    { base_relation.rename(:id => :user_id) }
      let(:projection) { operand.project([ :user_id, :name ])  }

      it_should_behave_like 'a generated SQL SELECT query'

      its(:to_s)     { pending { should eql('SELECT DISTINCT "id" AS "user_id", "name" FROM "users"') } }
      its(:to_inner) { pending { should eql('SELECT DISTINCT "id" AS "user_id", "name" FROM "users"') } }
    end

    context 'when the projection does not include the renamed column' do
      let(:operand)    { base_relation.rename(:id => :user_id) }
      let(:projection) { operand.project([ :name, :age ])  }

      it_should_behave_like 'a generated SQL SELECT query'

      its(:to_s)     { should eql('SELECT DISTINCT "name", "age" FROM (SELECT "id" AS "user_id", "name", "age" FROM "users") AS "users"') }
      its(:to_inner) { should eql('SELECT DISTINCT "name", "age" FROM (SELECT "id" AS "user_id", "name", "age" FROM "users") AS "users"') }
    end
  end

  context 'when the operand is a restriction' do
    let(:operand) { base_relation.restrict { |r| r[:id].eq(1) } }

    it_should_behave_like 'a generated SQL SELECT query'

    its(:to_s)     { should eql('SELECT DISTINCT "id", "name" FROM "users" WHERE "id" = 1') }
    its(:to_inner) { should eql('SELECT DISTINCT "id", "name" FROM "users" WHERE "id" = 1') }
  end

  context 'when the operand is ordered' do
    let(:operand) { base_relation.order }

    it_should_behave_like 'a generated SQL SELECT query'

    its(:to_s)     { should eql('SELECT DISTINCT "id", "name" FROM (SELECT * FROM "users" ORDER BY "id", "name", "age") AS "users"') }
    its(:to_inner) { should eql('SELECT DISTINCT "id", "name" FROM (SELECT * FROM "users" ORDER BY "id", "name", "age") AS "users"') }
  end

  context 'when the operand is reversed' do
    let(:operand) { base_relation.order.reverse }

{'fraction_non_alphanumeric': 0.14184602051133902, 'fraction_numerical': 0.0017333525928065867, 'mean_word_length': 2.857381615598886, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '539259', 'n_tokens_mistral': 2298, 'n_tokens_neox': 2210, 'n_words': 636}