Repository: prestodb/presto
Issue: INSERT should ignore hidden columns

When doing an `INSERT` that does not specify the column list (which is not yet supported), the column list should only be the visible columns (not hidden columns). Thus, it should be equivalent to the columns returned by `SELECT * FROM t`.

For example, using the tpch connector:

```
presto:tiny> describe region;
  Column   |  Type   | Null | Partition Key | Comment 
-----------+---------+------+---------------+---------
 regionkey | bigint  | true | false         |         
 name      | varchar | true | false         |         
 comment   | varchar | true | false         |         
(3 rows)

presto:tiny> select * from region limit 0;
 regionkey | name | comment 
-----------+------+---------
(0 rows)
```

However, the check in `StatementAnalyzer` is including the hidden `row_number` columns:

```
presto:tiny> insert into region select * from region;
Query 20150129_235057_00017_b9dwj failed: Insert query has mismatched column types: Table: (bigint, varchar, varchar, bigint), Query: (bigint, varchar, varchar)
```


Changed files:
presto-main/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java
presto-main/src/test/java/com/facebook/presto/sql/analyzer/TestAnalyzer.java

diff --git a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java
index 56dea1fa03..163872a2a1 100644
--- a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java
+++ b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java
@@ -55,6 +55,7 @@ import com.facebook.presto.sql.tree.Values;
 import com.facebook.presto.sql.tree.With;
 import com.facebook.presto.sql.tree.WithQuery;
 import com.google.common.base.Joiner;
+import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableList;
 import com.google.common.primitives.Ints;
 
@@ -364,7 +365,9 @@ class StatementAnalyzer
         analysis.setInsertTarget(targetTableHandle.get());
 
         List<ColumnMetadata> columns = metadata.getTableMetadata(targetTableHandle.get()).getColumns();
-        Iterable<Type> tableTypes = transform(columns, ColumnMetadata::getType);
+        Iterable<Type> tableTypes = FluentIterable.from(columns)
+                .filter(column -> !column.isHidden())
+                .transform(ColumnMetadata::getType);
 
         Iterable<Type> queryTypes = transform(descriptor.getVisibleFields(), Field::getType);
 
diff --git a/presto-main/src/test/java/com/facebook/presto/sql/analyzer/TestAnalyzer.java b/presto-main/src/test/java/com/facebook/presto/sql/analyzer/TestAnalyzer.java
index b4baa460b0..2ac118f284 100644
--- a/presto-main/src/test/java/com/facebook/presto/sql/analyzer/TestAnalyzer.java
+++ b/presto-main/src/test/java/com/facebook/presto/sql/analyzer/TestAnalyzer.java
@@ -480,6 +480,22 @@ public class TestAnalyzer
         analyze("WITH AB AS (SELECT * FROM t1) SELECT * FROM ab");
     }
 
+    @Test
+    public void testInsert()
+            throws Exception
+    {
+        analyze("INSERT INTO t1 SELECT * FROM t1");
+        analyze("INSERT INTO t3 SELECT * FROM t3");
+        analyze("INSERT INTO t3 SELECT a, b FROM t3");
+        assertFails(MISMATCHED_SET_COLUMN_TYPES, "INSERT INTO t1 VALUES (1, 2)");
+
+        // ignore t5 hidden column
+        analyze("INSERT INTO t5 VALUES (1)");
+
+        // fail if hidden column provided
+        assertFails(MISMATCHED_SET_COLUMN_TYPES, "INSERT INTO t5 VALUES (1, 2)");
+    }
+
     @Test
     public void testDuplicateWithQuery()
             throws Exception
@@ -751,7 +767,8 @@ public class TestAnalyzer
         metadata.createTable(SESSION, "tpch", new TableMetadata("tpch", new ConnectorTableMetadata(table3,
                 ImmutableList.<ColumnMetadata>of(
                         new ColumnMetadata("a", BIGINT, 0, false),
-                        new ColumnMetadata("b", BIGINT, 1, false)))));
+                        new ColumnMetadata("b", BIGINT, 1, false),
+                        new ColumnMetadata("x", BIGINT, 2, false, null, true)))));
 
         // table in different catalog
         SchemaTableName table4 = new SchemaTableName("s2", "t4");
@@ -759,6 +776,13 @@ public class TestAnalyzer
                 ImmutableList.<ColumnMetadata>of(
                         new ColumnMetadata("a", BIGINT, 0, false)))));
 
+        // table with a hidden column
+        SchemaTableName table5 = new SchemaTableName("default", "t5");
+        metadata.createTable(SESSION, "tpch", new TableMetadata("tpch", new ConnectorTableMetadata(table5,
+                ImmutableList.<ColumnMetadata>of(
+                        new ColumnMetadata("a", BIGINT, 0, false),
+                        new ColumnMetadata("b", BIGINT, 1, false, null, true)))));
+
         // valid view referencing table in same schema
         String viewData1 = JsonCodec.jsonCodec(ViewDefinition.class).toJson(
                 new ViewDefinition("select a from t1", "tpch", "default", ImmutableList.of(