/**
 * Copyright (C) 2011 Akiban Technologies Inc.
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 */

package com.akiban.server.test.it.bugs.bug696156;

import com.akiban.server.api.dml.scan.ScanAllRequest;
import com.akiban.server.error.DuplicateKeyException;
import com.akiban.server.error.InvalidOperationException;
import com.akiban.server.test.it.ITBase;
import org.junit.Assert;
import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class MultipleNullUniqueIndexIT  extends ITBase {

    @Test
    public void reportTestCase() throws InvalidOperationException {
        final int tid = createTable("test", "t1", "c1 TINYINT AUTO_INCREMENT NULL UNIQUE KEY");
        writeRows(createNewRow(tid, null, -1L));
        writeRows(createNewRow(tid, null, -1L));
        expectFullRows(tid,
                       createNewRow(tid, (Object)null),
                       createNewRow(tid, (Object)null));
    }

    @Test
    public void singleColumnUniqueWithNulls() throws InvalidOperationException {
        final int tid = createTable("test", "t1", "id int key, name varchar(32), unique(name)");
        writeRows(createNewRow(tid, 1, "abc"),
                  createNewRow(tid, 2, "def"),
                  createNewRow(tid, 3, null),
                  createNewRow(tid, 4, "ghi"),
                  createNewRow(tid, 5, null));
        assertEquals(5, scanAll(new ScanAllRequest(tid, null)).size());

        try {
            writeRows(createNewRow(tid, 6, "abc"));
            Assert.fail("DuplicateKeyException expected");
        }
        catch(DuplicateKeyException e) {
        }
    }

    @Test
    public void multiColumnUniqueWithNulls() throws InvalidOperationException {
        final int tid = createTable("test", "t1", "id int key, seg1 int, seg2 int, seg3 int, unique(seg1,seg2,seg3)");
        writeRows(createNewRow(tid, 1, 1, 1, 1),
                  createNewRow(tid, 2, 1, 1, null),
                  createNewRow(tid, 3, 1, null, 1),
                  createNewRow(tid, 4, 1, null, null),
                  createNewRow(tid, 5, null, 1, 1),
                  createNewRow(tid, 6, null, 1, null),
                  createNewRow(tid, 7, null, null, null),
                  createNewRow(tid, 8, null, null, null));
        assertEquals(8, scanAll(new ScanAllRequest(tid, null)).size());

        try {
            writeRows(createNewRow(tid, 9, 1, 1, 1));
            Assert.fail("DuplicateKeyException expected");
        }
        catch(DuplicateKeyException e) {
        }
    }

    @Test
    public void singleColumnIndexWithNulls() throws InvalidOperationException {
        final int tid = createTable("test", "t1", "id int key, name varchar(32), index(name)");
        writeRows(createNewRow(tid, 1, "abc"),
                  createNewRow(tid, 2, "def"),
                  createNewRow(tid, 3, "abc"),
                  createNewRow(tid, 4, null),
                  createNewRow(tid, 5, null));
        assertEquals(5, scanAll(new ScanAllRequest(tid, null)).size());
    }

    @Test
    public void multiColumnIndexWithNulls() throws InvalidOperationException {
        final int tid = createTable("test", "t1", "id int key, seg1 int, seg2 int, index(seg1,seg2)");
        writeRows(createNewRow(tid, 1, 1, 1),
                  createNewRow(tid, 2, 2, 2),
                  createNewRow(tid, 3, 1, 1),
                  createNewRow(tid, 4, 1, null),
                  createNewRow(tid, 5, null, 1),
                  createNewRow(tid, 6, 1, null),
                  createNewRow(tid, 7, null, 1),
                  createNewRow(tid, 8, null, null),
                  createNewRow(tid, 9, null, null));
        assertEquals(9, scanAll(new ScanAllRequest(tid, null)).size());
    }
}

@@ -701,16 +701,56 @@
 96156;%0A%0A
+import com.akiban.ais.model.AISBuilder;%0A
 import c
@@ -795,16 +795,16 @@
 equest;%0A
-
 import c
@@ -1191,95 +1191,600 @@
     
-final int tid = createTable(%22test%22, %22t
+String SCHEMA = %22test%22;%0A        String TABLE = %22t1%22;%0A        String COLUMN = %22c1%22;%0A        AISBuilder builder = new AISBuilder();%0A        builder.userTable(SCHEMA, TABLE);%0A        builder.column(SCHEMA, TABLE, COLUMN, 0, %22TINYINT%22, null, null, true, true, null, null);%0A        builder.index(SCHEMA, TABLE, %22c
 1%22, 
-%22c1 TINYINT AUTO_INCREMENT NULL UNIQUE KEY%22);
+true, %22UNIQUE%22);%0A        builder.indexColumn(SCHEMA, TABLE, COLUMN, COLUMN, 0, true, null);%0A        ddl().createTable(session(), builder.akibanInformationSchema().getUserTable(SCHEMA, TABLE));%0A        updateAISGeneration();%0A        final int tid = tableId(SCHEMA, TABLE);%0A        
 %0A   
@@ -2167,32 +2167,49 @@
 , %22t1%22, %22id int 
+not null primary 
 key, name varcha
@@ -2871,32 +2871,49 @@
 , %22t1%22, %22id int 
+not null primary 
 key, seg1 int, s
@@ -3801,24 +3801,41 @@
 1%22, %22id int 
+not null primary 
 key, name va
@@ -3847,21 +3847,59 @@
 (32)
-, index(name)
+%22);%0A        createIndex(%22test%22, %22t1%22, %22name%22, %22name
 %22);%0A
@@ -4358,16 +4358,33 @@
 %22id int 
+not null primary 
 key, seg
@@ -4402,26 +4402,67 @@
  int
-, index(seg1,
+%22);%0A        createIndex(%22test%22, %22t1%22, %22seg1%22, %22seg1%22, %22
 seg2
-)
 %22);%0A

Fix MultipleNullUniqueIndexIT schemas