[ https://issues.apache.org/jira/browse/DRILL-7502?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Paul Rogers updated DRILL-7502: ------------------------------- Description: The {{typeof()}} function is defined as follows: {code:java} @FunctionTemplate(names = {"typeOf"}, scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.INTERNAL) public static class GetType implements DrillSimpleFunc { @Param FieldReader input; @Output VarCharHolder out; @Inject DrillBuf buf; @Override public void setup() {} @Override public void eval() { String typeName = input.getTypeString(); byte[] type = typeName.getBytes(); buf = buf.reallocIfNeeded(type.length); buf.setBytes(0, type); out.buffer = buf; out.start = 0; out.end = type.length; } } {code} Note that the {{input}} field is defined as {{FieldReader}} which has a method called {{getTypeString()}}. As a result, the code works fine in all existing tests in {{TestTypeFns}}. I tried to add a function to use {{typeof()}} on a column of type {{UNION}}. When I did, the query failed with a compile error in generated code: {noformat} SYSTEM ERROR: CompileException: Line 42, Column 43: A method named "getTypeString" is not declared in any enclosing class nor any supertype, nor through a static import {noformat} The stack trace shows the generated code; Note that the type of {{input}} changes from a reader to a holder, causing code to be invalid: {code:java} public class ProjectorGen0 { DrillBuf work0; UnionVector vv1; VarCharVector vv6; DrillBuf work9; VarCharVector vv11; DrillBuf work14; VarCharVector vv16; public void doEval(int inIndex, int outIndex) throws SchemaChangeException { { UnionHolder out4 = new UnionHolder(); { out4 .isSet = vv1 .getAccessor().isSet((inIndex)); if (out4 .isSet == 1) { vv1 .getAccessor().get((inIndex), out4); } } //---- start of eval portion of typeOf function. ----// VarCharHolder out5 = new VarCharHolder(); { final VarCharHolder out = new VarCharHolder(); UnionHolder input = out4; DrillBuf buf = work0; UnionFunctions$GetType_eval: { String typeName = input.getTypeString(); byte[] type = typeName.getBytes(); buf = buf.reallocIfNeeded(type.length); buf.setBytes(0, type); out.buffer = buf; out.start = 0; out.end = type.length; } {code} By contrast, here is the generated code for one of the existing {{TestTypeFns}} tests where things work: {code:java} public class ProjectorGen0 extends ProjectorTemplate { DrillBuf work0; NullableBigIntVector vv1; VarCharVector vv7; public ProjectorGen0() { try { __DRILL_INIT__(); } catch (SchemaChangeException e) { throw new UnsupportedOperationException(e); } } public void doEval(int inIndex, int outIndex) throws SchemaChangeException { { .. //---- start of eval portion of typeOf function. ----// VarCharHolder out6 = new VarCharHolder(); { final VarCharHolder out = new VarCharHolder(); FieldReader input = new NullableIntHolderReaderImpl(out5); DrillBuf buf = work0; UnionFunctions$GetType_eval: { String typeName = input.getTypeString(); byte[] type = typeName.getBytes(); buf = buf.reallocIfNeeded(type.length); buf.setBytes(0, type); out.buffer = buf; out.start = 0; out.end = type.length; } work0 = buf; out6 .start = out.start; out6 .end = out.end; out6 .buffer = out.buffer; } //---- end of eval portion of typeOf function. ----// {code} Notice that the {{input}} variable is of type {{FieldReader}} as expected. Queries that work: {code:java} String sql = "SELECT typeof(CAST(a AS " + castType + ")) FROM (VALUES (1)) AS T(a)"; sql = "SELECT typeof(CAST(a AS " + castType + ")) FROM cp.`functions/null.json`"; String sql = "SELECT typeof(" + expr + ") FROM (VALUES (" + value + ")) AS T(a)"; {code} Query that fails: {code:java} String sql ="SELECT typeof(a) AS t, modeof(a) as m, drilltypeof(a) AS dt\n" + "FROM cp.`jsoninput/union/c.json`"; {code} The queries that work all include either a CAST or constant values. The query that fails works with data read from a file. Also, the queries that work use scalar types, the query that fails uses the UNION type. was: The {{typeof()}} function is defined as follows: {code:java} @FunctionTemplate(names = {"typeOf"}, scope = FunctionTemplate.FunctionScope.SIMPLE, nulls = NullHandling.INTERNAL) public static class GetType implements DrillSimpleFunc { @Param FieldReader input; @Output VarCharHolder out; @Inject DrillBuf buf; @Override public void setup() {} @Override public void eval() { String typeName = input.getTypeString(); byte[] type = typeName.getBytes(); buf = buf.reallocIfNeeded(type.length); buf.setBytes(0, type); out.buffer = buf; out.start = 0; out.end = type.length; } } {code} Note that the {{input}} field is defined as {{FieldReader}} which has a method called {{getTypeString()}}. As a result, the code works fine in all existing tests in {{TestTypeFns}}. I tried to add a function to use {{typeof()}} on a column of type {{UNION}}. When I did, the query failed with a compile error in generated code: {noformat} SYSTEM ERROR: CompileException: Line 42, Column 43: A method named "getTypeString" is not declared in any enclosing class nor any supertype, nor through a static import {noformat} The stack trace shows the generated code; Note that the type of {{input}} changes from a reader to a holder, causing code to be invalid: {code:java} public class ProjectorGen0 { DrillBuf work0; UnionVector vv1; VarCharVector vv6; DrillBuf work9; VarCharVector vv11; DrillBuf work14; VarCharVector vv16; public void doEval(int inIndex, int outIndex) throws SchemaChangeException { { UnionHolder out4 = new UnionHolder(); { out4 .isSet = vv1 .getAccessor().isSet((inIndex)); if (out4 .isSet == 1) { vv1 .getAccessor().get((inIndex), out4); } } //---- start of eval portion of typeOf function. ----// VarCharHolder out5 = new VarCharHolder(); { final VarCharHolder out = new VarCharHolder(); UnionHolder input = out4; DrillBuf buf = work0; UnionFunctions$GetType_eval: { String typeName = input.getTypeString(); byte[] type = typeName.getBytes(); buf = buf.reallocIfNeeded(type.length); buf.setBytes(0, type); out.buffer = buf; out.start = 0; out.end = type.length; } {code} By contrast, here is the generated code for one of the existing {{TestTypeFns}} tests where things work: {code:java} public class ProjectorGen0 extends ProjectorTemplate { DrillBuf work0; NullableBigIntVector vv1; VarCharVector vv7; public ProjectorGen0() { try { __DRILL_INIT__(); } catch (SchemaChangeException e) { throw new UnsupportedOperationException(e); } } public void doEval(int inIndex, int outIndex) throws SchemaChangeException { { .. //---- start of eval portion of typeOf function. ----// VarCharHolder out6 = new VarCharHolder(); { final VarCharHolder out = new VarCharHolder(); FieldReader input = new NullableIntHolderReaderImpl(out5); DrillBuf buf = work0; UnionFunctions$GetType_eval: { String typeName = input.getTypeString(); byte[] type = typeName.getBytes(); buf = buf.reallocIfNeeded(type.length); buf.setBytes(0, type); out.buffer = buf; out.start = 0; out.end = type.length; } work0 = buf; out6 .start = out.start; out6 .end = out.end; out6 .buffer = out.buffer; } //---- end of eval portion of typeOf function. ----// {code} Notice that the {{input}} variable is of type {{FieldReader}} as expected. > Incorrect/invalid codegen for typeof() with UNION > ------------------------------------------------- > > Key: DRILL-7502 > URL: https://issues.apache.org/jira/browse/DRILL-7502 > Project: Apache Drill > Issue Type: Bug > Reporter: Paul Rogers > Priority: Major > > The {{typeof()}} function is defined as follows: > {code:java} > @FunctionTemplate(names = {"typeOf"}, > scope = FunctionTemplate.FunctionScope.SIMPLE, > nulls = NullHandling.INTERNAL) > public static class GetType implements DrillSimpleFunc { > @Param > FieldReader input; > @Output > VarCharHolder out; > @Inject > DrillBuf buf; > @Override > public void setup() {} > @Override > public void eval() { > String typeName = input.getTypeString(); > byte[] type = typeName.getBytes(); > buf = buf.reallocIfNeeded(type.length); > buf.setBytes(0, type); > out.buffer = buf; > out.start = 0; > out.end = type.length; > } > } > {code} > Note that the {{input}} field is defined as {{FieldReader}} which has a > method called {{getTypeString()}}. As a result, the code works fine in all > existing tests in {{TestTypeFns}}. > I tried to add a function to use {{typeof()}} on a column of type {{UNION}}. > When I did, the query failed with a compile error in generated code: > {noformat} > SYSTEM ERROR: CompileException: Line 42, Column 43: > A method named "getTypeString" is not declared in any enclosing class nor > any supertype, nor through a static import > {noformat} > The stack trace shows the generated code; Note that the type of {{input}} > changes from a reader to a holder, causing code to be invalid: > {code:java} > public class ProjectorGen0 { > DrillBuf work0; > UnionVector vv1; > VarCharVector vv6; > DrillBuf work9; > VarCharVector vv11; > DrillBuf work14; > VarCharVector vv16; > public void doEval(int inIndex, int outIndex) > throws SchemaChangeException > { > { > UnionHolder out4 = new UnionHolder(); > { > out4 .isSet = vv1 .getAccessor().isSet((inIndex)); > if (out4 .isSet == 1) { > vv1 .getAccessor().get((inIndex), out4); > } > } > //---- start of eval portion of typeOf function. ----// > VarCharHolder out5 = new VarCharHolder(); > { > final VarCharHolder out = new VarCharHolder(); > UnionHolder input = out4; > DrillBuf buf = work0; > UnionFunctions$GetType_eval: > { > String typeName = input.getTypeString(); > byte[] type = typeName.getBytes(); > buf = buf.reallocIfNeeded(type.length); > buf.setBytes(0, type); > out.buffer = buf; > out.start = 0; > out.end = type.length; > } > {code} > By contrast, here is the generated code for one of the existing > {{TestTypeFns}} tests where things work: > {code:java} > public class ProjectorGen0 > extends ProjectorTemplate > { > DrillBuf work0; > NullableBigIntVector vv1; > VarCharVector vv7; > public ProjectorGen0() { > try { > __DRILL_INIT__(); > } catch (SchemaChangeException e) { > throw new UnsupportedOperationException(e); > } > } > public void doEval(int inIndex, int outIndex) > throws SchemaChangeException > { > { > .. > //---- start of eval portion of typeOf function. ----// > VarCharHolder out6 = new VarCharHolder(); > { > final VarCharHolder out = new VarCharHolder(); > FieldReader input = new NullableIntHolderReaderImpl(out5); > DrillBuf buf = work0; > UnionFunctions$GetType_eval: > { > String typeName = input.getTypeString(); > byte[] type = typeName.getBytes(); > buf = buf.reallocIfNeeded(type.length); > buf.setBytes(0, type); > out.buffer = buf; > out.start = 0; > out.end = type.length; > } > work0 = buf; > out6 .start = out.start; > out6 .end = out.end; > out6 .buffer = out.buffer; > } > //---- end of eval portion of typeOf function. ----// > {code} > Notice that the {{input}} variable is of type {{FieldReader}} as expected. > Queries that work: > {code:java} > String sql = "SELECT typeof(CAST(a AS " + castType + ")) FROM (VALUES > (1)) AS T(a)"; > sql = "SELECT typeof(CAST(a AS " + castType + ")) FROM > cp.`functions/null.json`"; > String sql = "SELECT typeof(" + expr + ") FROM (VALUES (" + value + ")) > AS T(a)"; > {code} > Query that fails: > {code:java} > String sql ="SELECT typeof(a) AS t, modeof(a) as m, drilltypeof(a) AS > dt\n" + > "FROM cp.`jsoninput/union/c.json`"; > {code} > The queries that work all include either a CAST or constant values. The query > that fails works with data read from a file. Also, the queries that work use > scalar types, the query that fails uses the UNION type. -- This message was sent by Atlassian Jira (v8.3.4#803005)