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

[CALCITE-3486] In JDBC adapter, when generating ROW value expression, generates the ROW keyword only if the dialect allows it (quxiucheng) #1568

Closed
wants to merge 1 commit into from

Conversation

quxiucheng
Copy link

MysqlSqlDialect unparse ROW keyword does not exist

@@ -3699,6 +3700,14 @@ void checkPeriodPredicate(Checker checker) {
.ok(expected);
}

@Test public void testInsertDialect() {
// See [CALCITE-3486] MysqlSqlDialect unparse ROW keyword does not exist
Copy link
Contributor

@amaliujia amaliujia Nov 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this comment. If you actually want to say this test is testing ROW, you can rename this test as testInsertWithRowDialect.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you.
modified

@amaliujia
Copy link
Contributor

LGTM

@@ -179,6 +179,9 @@ public boolean supportsAliasedValues() {

unparseFloor(writer, call);
break;
case ROW:
unparseRow(writer, call);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix @quxiucheng, i think this patch can be promoted a little, we can move this logic to the parent class SqlDialect, you can get the SqlConformance from the dialect and decide if we should generates the ROW keyword based on method SqlConformance#allowExplicitRowValueConstructor .

[1]

boolean allowExplicitRowValueConstructor();

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.
but the class SqlDialect can't get the method SqlConformance#allowExplicitRowValueConstructor correctly. I added a field in the class SqlDialect, Same as the field 'SqlConformance#allowExplicitRowValueConstructor'

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by "can not get method correctly", for MySQL, the conformance is SqlConformanceEnum.MYSQL_5 which i think is correct.

[1]

@Nonnull public SqlConformance getConformance() {

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have two ways of creating dialects.

  1. XxxSqlDialect.DEFAULT
  2. SqlDialect.DatabaseProduct.XXX.getDialect()

If we only call org.apache.calcite.sql.SqlDialect#getConformance this method to get conformance.
Only compatible SqlDialect.DatabaseProduct.XXX.getDialect() method. So I reset a parameter allowExplicitRowValueConstructor to be compatible with both ways of creating the dialect.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

XxxSqlDialect.DEFAULT also works, if we have set up the DatabaseProduct correctly. There is no overridden of method SqlDialect#getConformance, so i believe the behavior is correct.

Copy link
Author

@quxiucheng quxiucheng Nov 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see.Thanks.

I have a question:

the method SqlConformanceEnum#allowExplicitRowValueConstructor

  public boolean allowExplicitRowValueConstructor() {
    switch (this) {
    case DEFAULT:
    case LENIENT:
      return true;
    default:
      return false;
    }
  }

Only SqlConformanceEnum#DEFAULT and SqlConformanceEnum#LENIENT return values are true.
If this standard doesn't change. Test classes are mostly used by default method SqlConformanceEnum#PRAGMATIC_2003,
unparse will then have a lot of ROW keyword changes. Because they don't support the ROW keyword.
Should I add SqlConformanceEnum#PRAGMATIC_2003 to a method SqlConformanceEnum#allowExplicitRowValueConstructor or change the test class.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return value "true" means we would print the "ROW" keyword, for SqlConformanceEnum#PRAGMATIC_2003, it is expected to not allows that.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'm going to rewrite the code

@@ -3699,6 +3700,13 @@ void checkPeriodPredicate(Checker checker) {
.ok(expected);
}

@Test public void testInsertWithRowDialect() {
final String expected = "INSERT INTO `emps`\n"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can rename this method to testRowValueExpression and we should test dialect that allows/not allow explicit ROW keywords.

@danny0405 danny0405 changed the title [CALCITE-3486]MysqlSqlDialect unparse ROW keyword does not exist [CALCITE-3486] In JDBC adapter, when generating ROW value expression, generates the ROW keyword only if the dialect allows it (quxiucheng) Nov 10, 2019
@quxiucheng quxiucheng force-pushed the CALCITE-3486 branch 3 times, most recently from ce9dffa to 5357f0c Compare November 10, 2019 14:21
@@ -158,6 +158,7 @@
private final Casing unquotedCasing;
private final Casing quotedCasing;
private final boolean caseSensitive;
private final boolean allowExplicitRowValueConstructor;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this allowExplicitRowValueConstructor flag, we expect to get this info from the SqlConformance.

expected = "INSERT INTO `emps`\n"
+ "VALUES (1, 'Fred'),\n"
+ "(2, 'Eric')";
sql("insert into emps values (1,'Fred'),(2, 'Eric')")
Copy link
Contributor

@yanlin-Lynn yanlin-Lynn Nov 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why different value for sql() method? Shall we use the same.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry,I didn't notice that
Write the wrong

@quxiucheng quxiucheng force-pushed the CALCITE-3486 branch 2 times, most recently from d0a6a47 to bb45dbc Compare November 12, 2019 09:45
}
if (writer.isAlwaysUseParentheses()) {
for (SqlNode operand : call.getOperandList()) {
writer.sep(",");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain why we need this decision ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isAlwaysUseParentheses parameter will link operations with parentheses.
For example ,
(a + b) * c.The fully-parenthesized expression, ((a + b) * c)

If this parameter is in the SqlRowOperator. There will be extra parentheses
For example,
isAlwaysUseParentheses=true and allowExplicitRowValueConstructor=false

input expression:
insert into emp valuse (1,'a')

unparse result:
insert into emp valuse ((1,'a'))

I think this is a wrong SQL.

@@ -82,7 +82,7 @@ public void unparse(
SqlCall call,
int leftPrec,
int rightPrec) {
SqlUtil.unparseFunctionSyntax(this, writer, call);
writer.getDialect().unparseRow(writer, call, leftPrec, rightPrec);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not modify the unparse logic of SqlRowOperator, instead in SqlDialect, match the ROW call and unparse it specifically.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay. done

… generates the ROW keyword only if the dialect allows it
@danny0405 danny0405 closed this in ce0118b Nov 17, 2019
XuQianJin-Stars pushed a commit to XuQianJin-Stars/calcite that referenced this pull request Nov 17, 2019
… generates the ROW keyword only if the dialect allows it (quxiucheng)

In JDBC adapter, unparse the ROW keyword for ROW value expression only
if the SQL dialect allows it.

Fix-up (by Danny):
* Simplify the logic for ROW value expression in SqlDialect#unparseCall
* Add test cases in RelToSqlConverterTest
* Fix SqlParserTest, there is no need to introduce new kind of SQL
dialect

close apache#1568
XuQianJin-Stars pushed a commit to XuQianJin-Stars/calcite that referenced this pull request Nov 20, 2019
… generates the ROW keyword only if the dialect allows it (quxiucheng)

In JDBC adapter, unparse the ROW keyword for ROW value expression only
if the SQL dialect allows it.

Fix-up (by Danny):
* Simplify the logic for ROW value expression in SqlDialect#unparseCall
* Add test cases in RelToSqlConverterTest
* Fix SqlParserTest, there is no need to introduce new kind of SQL
dialect

close apache#1568
XuQianJin-Stars pushed a commit to XuQianJin-Stars/calcite that referenced this pull request Nov 20, 2019
… generates the ROW keyword only if the dialect allows it (quxiucheng)

In JDBC adapter, unparse the ROW keyword for ROW value expression only
if the SQL dialect allows it.

Fix-up (by Danny):
* Simplify the logic for ROW value expression in SqlDialect#unparseCall
* Add test cases in RelToSqlConverterTest
* Fix SqlParserTest, there is no need to introduce new kind of SQL
dialect

close apache#1568
wangxlong pushed a commit to wangxlong/calcite that referenced this pull request Feb 13, 2020
… generates the ROW keyword only if the dialect allows it (quxiucheng)

In JDBC adapter, unparse the ROW keyword for ROW value expression only
if the SQL dialect allows it.

Fix-up (by Danny):
* Simplify the logic for ROW value expression in SqlDialect#unparseCall
* Add test cases in RelToSqlConverterTest
* Fix SqlParserTest, there is no need to introduce new kind of SQL
dialect

close apache#1568
vvysotskyi pushed a commit to datadistillr/drill-calcite that referenced this pull request Oct 19, 2021
… generates the ROW keyword only if the dialect allows it (quxiucheng)

In JDBC adapter, unparse the ROW keyword for ROW value expression only
if the SQL dialect allows it.

Fix-up (by Danny):
* Simplify the logic for ROW value expression in SqlDialect#unparseCall
* Add test cases in RelToSqlConverterTest
* Fix SqlParserTest, there is no need to introduce new kind of SQL
dialect

close apache/calcite#1568

(cherry picked from commit ce0118b)
vvysotskyi pushed a commit to vvysotskyi/drill-calcite that referenced this pull request Oct 19, 2021
… generates the ROW keyword only if the dialect allows it (quxiucheng)

In JDBC adapter, unparse the ROW keyword for ROW value expression only
if the SQL dialect allows it.

Fix-up (by Danny):
* Simplify the logic for ROW value expression in SqlDialect#unparseCall
* Add test cases in RelToSqlConverterTest
* Fix SqlParserTest, there is no need to introduce new kind of SQL
dialect

close apache/calcite#1568

(cherry picked from commit ce0118b)
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

Successfully merging this pull request may close these issues.

4 participants