Hello Julian,

Not very convenient to not be part of the mailing list when asking questions, 
good that the calcite-dev archives list responses. :) 

But here is my claim:

The query:

SELECT *
FROM "GOSALESMR"."PRODUCT_SURVEY_RESULTS"
INNER JOIN "GOSALESMR"."PRODUCT_SURVEY_TOPIC" ON 
"PRODUCT_SURVEY_RESULTS"."PRODUCT_TOPIC_CODE"
= "PRODUCT_SURVEY_TOPIC".”PRODUCT_TOPIC_CODE”


Using squirrel returns: (as well as with Drill)
Error: DB2 SQL Error: SQLCODE=-206, SQLSTATE=42703, 
SQLERRMC=PRODUCT_SURVEY_RESULTS.PRODUCT_TOPIC_CODE, DRIVER=4.13.127
SQLState:  42703
ErrorCode: -206
Error: DB2 SQL Error: SQLCODE=-727, SQLSTATE=56098, 
SQLERRMC=2;-206;42703;PRODUCT_SURVEY_RESULTS.PRODUCT_TOPIC_CODE, DRIVER=4.13.127
SQLState:  56098
ErrorCode: -727



In Drill:

org.apache.drill.common.exceptions.UserRemoteException: DATA_READ ERROR: The 
JDBC storage plugin failed while trying setup the SQL query. sql SELECT * FROM 
"GOSALESMR"."PRODUCT_SURVEY_RESULTS" INNER JOIN 
"GOSALESMR"."PRODUCT_SURVEY_TOPIC" ON 
"PRODUCT_SURVEY_RESULTS"."PRODUCT_TOPIC_CODE" = 
"PRODUCT_SURVEY_TOPIC"."PRODUCT_TOPIC_CODE" plugin gs_db2 Fragment 0:0 [Error 
Id: 9e5c6edc-8572-4de2-b9ad-dce8a74589b1 on mpie-mbp.lan:31010] 
(com.ibm.db2.jcc.am.SqlSyntaxErrorException) DB2 SQL Error: SQLCODE=-206, 
SQLSTATE=42703, SQLERRMC=PRODUCT_SURVEY_RESULTS.PRODUCT_TOPIC_CODE, 
DRIVER=4.13.127 com.ibm.db2.jcc.am.id.a():677 com.ibm.db2.jcc.am.id.a():60 
com.ibm.db2.jcc.am.id.a():127 com.ibm.db2.jcc.am.no.c():2653 
com.ibm.db2.jcc.am.no.d():2641 com.ibm.db2.jcc.am.no.a():2090 
com.ibm.db2.jcc.t4.cb.h():141 com.ibm.db2.jcc.t4.cb.b():41 
com.ibm.db2.jcc.t4.q.a():32 com.ibm.db2.jcc.t4.sb.i():135 
com.ibm.db2.jcc.am.no.ib():2059 com.ibm.db2.jcc.am.no.a():3130 
com.ibm.db2.jcc.am.no.a():688 com.ibm.db2.jcc.am.no.executeQuery():672 
org.apache.commons.dbcp.DelegatingStatement.executeQuery():208 
org.apache.commons.dbcp.DelegatingStatement.executeQuery():208 
org.apache.drill.exec.store.jdbc.JdbcRecordReader.setup():177 
org.apache.drill.exec.physical.impl.ScanBatch.():108 
org.apache.drill.exec.physical.impl.ScanBatch.():136 
org.apache.drill.exec.store.jdbc.JdbcBatchCreator.getBatch():40 
org.apache.drill.exec.store.jdbc.JdbcBatchCreator.getBatch():33 
org.apache.drill.exec.physical.impl.ImplCreator.getRecordBatch():148 
org.apache.drill.exec.physical.impl.ImplCreator.getChildren():171 
org.apache.drill.exec.physical.impl.ImplCreator.getRecordBatch():128 
org.apache.drill.exec.physical.impl.ImplCreator.getChildren():171 
org.apache.drill.exec.physical.impl.ImplCreator.getRootExec():101 
org.apache.drill.exec.physical.impl.ImplCreator.getExec():79 
org.apache.drill.exec.work.fragment.FragmentExecutor.run():231 
org.apache.drill.common.SelfCleaningRunnable.run():38 
java.util.concurrent.ThreadPoolExecutor.runWorker():1145 
java.util.concurrent.ThreadPoolExecutor$Worker.run():615 
java.lang.Thread.run():745


With aliases in Squirrel:

SELECT * FROM "GOSALESMR"."PRODUCT_SURVEY_RESULTS" AS "PRODUCT_SURVEY_RESULTS" 
INNER JOIN "GOSALESMR"."PRODUCT_SURVEY_TOPIC" AS "PRODUCT_SURVEY_TOPIC" 
ON "PRODUCT_SURVEY_RESULTS"."PRODUCT_TOPIC_CODE" = 
"PRODUCT_SURVEY_TOPIC".”PRODUCT_TOPIC_CODE"

Returns all data with no errors or warnings.

SELECT * FROM "GOSALESMR"."PRODUCT_SURVEY_RESULTS" AS PRODUCT_SURVEY_RESULTS
INNER JOIN "GOSALESMR"."PRODUCT_SURVEY_TOPIC" AS PRODUCT_SURVEY_TOPIC 
ON "PRODUCT_SURVEY_RESULTS"."PRODUCT_TOPIC_CODE" = 
"PRODUCT_SURVEY_TOPIC"."PRODUCT_TOPIC_CODE"

Returns all data with no errors or warnings.

I distinctly remember this being the same behavior for both Netezza and 
Teradata for instance. (even though it was a few years since I really did lots 
of SQL on these systems). I can test Netezza but have no access to a TD box 
currently. 

Regards,
Magnus

—————————————

This is a response to:
—————————————

We originally generated an alias for every table in the FROM clause. But we 
discovered that
the aliases were not necessary and made the query less easy to understand. For 
example, the
query you mentioned earlier would become

SELECT *
FROM "GOSALESMR".”PRODUCT_SURVEY_RESULTS” AS T0
INNER JOIN "GOSALESMR"."PRODUCT_SURVEY_TOPIC” AS T1 ON T0."PRODUCT_TOPIC_CODE" 
= T1.”PRODUCT_TOPIC_CODE"

So, we add aliases only if the table aliases that are automatically generated 
by the target
system’s SQL validator are not unique.

This is the code that assigns aliases only if they are necessary:

public Result result(SqlNode node, Collection<Clause> clauses, RelNode rel) {
  final String alias2 = SqlValidatorUtil.getAlias(node, -1);
  final String alias3 = alias2 != null ? alias2 : "t";
  final String alias4 =
      SqlValidatorUtil.uniquify(
          alias3, aliasSet, SqlValidatorUtil.EXPR_SUGGESTER);
  final String alias5 = alias2 == null || !alias2.equals(alias4) ? alias4
      : null;
  return new Result(node, clauses, alias5,
      Collections.singletonList(Pair.of(alias4, rel.getRowType())));
}

You assert that 

SELECT *
FROM "GOSALESMR"."PRODUCT_SURVEY_RESULTS"
INNER JOIN "GOSALESMR"."PRODUCT_SURVEY_TOPIC" ON 
"PRODUCT_SURVEY_RESULTS"."PRODUCT_TOPIC_CODE"
= "PRODUCT_SURVEY_TOPIC".”PRODUCT_TOPIC_CODE”

is not correct, but I disagree. I think it is fine. My understanding is that 
the table "GOSALESMR".”PRODUCT_SURVEY_TOPIC”
will implicitly have an alias “PRODUCT_SURVEY_TOPIC” on all SQL systems, 
including DB2.
If my understanding is wrong, then we do indeed have a problem. Does that query 
fail to validate,
or give wrong results?

Julian



Reply via email to