Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception inserting a record of type row(integer) #5807

Closed
nezihyigitbasi opened this issue Aug 5, 2016 · 3 comments
Closed

Exception inserting a record of type row(integer) #5807

nezihyigitbasi opened this issue Aug 5, 2016 · 3 comments

Comments

@nezihyigitbasi
Copy link
Contributor

presto:nyigitbasi> desc row_test;
 Column |      Type      | Comment
--------+----------------+---------
 x      | row(A integer) |
(1 row)

presto:nyigitbasi> insert into row_test values(row(2));
Query 20160805_225100_00048_b6cxd failed: Insert query has mismatched column types: Table: [row(A integer)], Query: [integer]
com.facebook.presto.sql.analyzer.SemanticException: Insert query has mismatched column types: Table: [row(A integer)], Query: [integer]
        at com.facebook.presto.sql.analyzer.StatementAnalyzer.visitInsert(StatementAnalyzer.java:249)
        at com.facebook.presto.sql.analyzer.StatementAnalyzer.visitInsert(StatementAnalyzer.java:161)
        at com.facebook.presto.sql.tree.Insert.accept(Insert.java:61)
        at com.facebook.presto.sql.tree.AstVisitor.process(AstVisitor.java:22)
        at com.facebook.presto.sql.analyzer.Analyzer.analyze(Analyzer.java:62)
        at com.facebook.presto.execution.SqlQueryExecution.doAnalyzeQuery(SqlQueryExecution.java:273)
        at com.facebook.presto.execution.SqlQueryExecution.analyzeQuery(SqlQueryExecution.java:259)
        at com.facebook.presto.execution.SqlQueryExecution.start(SqlQueryExecution.java:223)
        at com.facebook.presto.execution.QueuedExecution.lambda$start$1(QueuedExecution.java:62)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

This part of the analyzer code smells bad to me, @martint any ideas?

@geraint0923
Copy link
Contributor

I think the problem is that in (row(2)) the outer parentheses is considered to change the evaluate priority and ignored when evaluating type. So your query is actually like:
insert into row_test values row(2)
and row(2) will seem as (2) which represents a row of data but a data type row just like
insert into some_table values (1,2,3) where some_table(a integer, b integer, c integer).

You can try
insert into row_test values row(row(2))
which will force the parser to produce what you expect.

The syntax is also confusing me sometimes.

@nezihyigitbasi
Copy link
Contributor Author

@geraint0923 thanks for the explanation. The double row call works with a cast insert into row_test values row(cast(row(2) as row(A integer)));.

But, is it just a confusion or is it a bug? row is interpreted differently within a values:

presto:nyigitbasi> select * from (values row(2));
 _col0
-------
     2
(1 row)

presto:nyigitbasi> select row(2);
   _col0
------------
 {field0=2}
(1 row)

presto:nyigitbasi> select * from (values row(row(2)));
   _col0
------------
 {field0=2}
(1 row)

@geraint0923
Copy link
Contributor

@nezihyigitbasi I agree with you that it is a little confusing. But I think it is intentional. When we are using values, we are actually trying to create an inline table which might has more than one columns. So we need to have a way to specify a row with multiple columns in a table, here we choose to use row.so in values, non-row and outer row will be regarded as a row of data in a table.

BTW, I just checked the SqlBase.g4:

primaryExpression
    : NULL                                             #nullLiteral
    ...
    | '(' expression (',' expression)+ ')'             #rowConstructor
    | ROW '(' expression (',' expression)* ')'         #rowConstructor
    ...
    | '(' expression ')'                               #parenthesizedExpression
    ;

(...) is a row only if there are more than one elements in it, and that is why (row(2)) is the same as row(2) which will be unwrapped in values clause.

@martint Maybe we need to clarify it in the docs?

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

No branches or pull requests

2 participants