[
https://issues.apache.org/jira/browse/DRILL-6524?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16790756#comment-16790756
]
Volodymyr Vysotskyi commented on DRILL-6524:
--------------------------------------------
In the second commit of the pull request, were made changes to avoid such cases
of reference assignment to allow producing a scalar replacement.
For the next query:
{code:sql}
select
case when expr$0 = 3 then expr$0 else expr$1 end,
case when expr$0 = 1 then expr$0 else expr$1 end
from (values(1, 2));
{code}
without the changes will be generated the next class:
{code:java}
package org.apache.drill.exec.test.generated;
import org.apache.drill.exec.exception.SchemaChangeException;
import org.apache.drill.exec.expr.holders.BigIntHolder;
import org.apache.drill.exec.expr.holders.IntHolder;
import org.apache.drill.exec.expr.holders.NullableBigIntHolder;
import org.apache.drill.exec.expr.holders.NullableBitHolder;
import org.apache.drill.exec.ops.FragmentContext;
import org.apache.drill.exec.physical.impl.project.ProjectorTemplate;
import org.apache.drill.exec.record.RecordBatch;
import org.apache.drill.exec.vector.NullableBigIntVector;
public class ProjectorGen0
extends ProjectorTemplate
{
NullableBigIntVector vv1;
IntHolder const5;
BigIntHolder constant7;
NullableBigIntVector vv9;
NullableBigIntVector vv13;
IntHolder const17;
BigIntHolder constant19;
NullableBigIntVector vv21;
NullableBigIntVector vv25;
public ProjectorGen0() {
try {
__DRILL_INIT__();
} catch (SchemaChangeException e) {
throw new UnsupportedOperationException(e);
}
}
public void doEval(int inIndex, int outIndex)
throws SchemaChangeException
{
{
NullableBigIntHolder out0 = new NullableBigIntHolder();
NullableBigIntHolder out4 = new NullableBigIntHolder();
{
out4 .isSet = vv1 .getAccessor().isSet((inIndex));
if (out4 .isSet == 1) {
out4 .value = vv1 .getAccessor().get((inIndex));
}
}
//---- start of eval portion of equal function. ----//
NullableBitHolder out8 = new NullableBitHolder();
{
if (out4 .isSet == 0) {
out8 .isSet = 0;
} else {
final NullableBitHolder out = new NullableBitHolder();
NullableBigIntHolder left = out4;
BigIntHolder right = constant7;
GCompareBigIntVsBigInt$EqualsBigIntVsBigInt_eval:
{
if (Double.isNaN(left.value) && Double.isNaN(right.value)) {
out.value = 1;
} else
{
out.value = left.value == right.value ? 1 : 0;
}
}
out.isSet = 1;
out8 = out;
out.isSet = 1;
}
}
//---- end of eval portion of equal function. ----//
if ((out8 .isSet == 1)&&(out8 .value == 1)) {
if (out4 .isSet!= 0) {
out0 = out4;
}
} else {
NullableBigIntHolder out12 = new NullableBigIntHolder();
{
out12 .isSet = vv9 .getAccessor().isSet((inIndex));
if (out12 .isSet == 1) {
out12 .value = vv9 .getAccessor().get((inIndex));
}
}
if (out12 .isSet!= 0) {
out0 = out12;
}
}
if (!(out0 .isSet == 0)) {
vv13 .getMutator().set((outIndex), out0 .isSet, out0 .value);
}
NullableBigIntHolder out16 = new NullableBigIntHolder();
//---- start of eval portion of equal function. ----//
NullableBitHolder out20 = new NullableBitHolder();
{
if (out4 .isSet == 0) {
out20 .isSet = 0;
} else {
final NullableBitHolder out = new NullableBitHolder();
NullableBigIntHolder left = out4;
BigIntHolder right = constant19;
GCompareBigIntVsBigInt$EqualsBigIntVsBigInt_eval:
{
if (Double.isNaN(left.value) && Double.isNaN(right.value)) {
out.value = 1;
} else
{
out.value = left.value == right.value ? 1 : 0;
}
}
out.isSet = 1;
out20 = out;
out.isSet = 1;
}
}
//---- end of eval portion of equal function. ----//
if ((out20 .isSet == 1)&&(out20 .value == 1)) {
if (out4 .isSet!= 0) {
out16 = out4;
}
} else {
NullableBigIntHolder out24 = new NullableBigIntHolder();
{
out24 .isSet = vv21 .getAccessor().isSet((inIndex));
if (out24 .isSet == 1) {
out24 .value = vv21 .getAccessor().get((inIndex));
}
}
if (out24 .isSet!= 0) {
out16 = out24;
}
}
if (!(out16 .isSet == 0)) {
vv25 .getMutator().set((outIndex), out16 .isSet, out16 .value);
}
}
}
public void doSetup(FragmentContext context, RecordBatch incoming,
RecordBatch outgoing)
throws SchemaChangeException
{
{
int[] fieldIds2 = new int[ 1 ] ;
fieldIds2 [ 0 ] = 0;
Object tmp3 =
(incoming).getValueAccessorById(NullableBigIntVector.class,
fieldIds2).getValueVector();
if (tmp3 == null) {
throw new SchemaChangeException("Failure while loading vector
vv1 with id: TypedFieldId [fieldIds=[0], remainder=null].");
}
vv1 = ((NullableBigIntVector) tmp3);
/** start SETUP for function castBIGINT **/
{
IntHolder in = const5;
CastIntBigInt_setup:
{}
}
/** end SETUP for function castBIGINT **/
//---- start of eval portion of castBIGINT function. ----//
BigIntHolder out6 = new BigIntHolder();
{
final BigIntHolder out = new BigIntHolder();
IntHolder in = const5;
CastIntBigInt_eval:
{
out.value = in.value;
}
out6 = out;
}
//---- end of eval portion of castBIGINT function. ----//
constant7 = out6;
/** start SETUP for function equal **/
{
BigIntHolder right = constant7;
GCompareBigIntVsBigInt$EqualsBigIntVsBigInt_setup:
{}
}
/** end SETUP for function equal **/
int[] fieldIds10 = new int[ 1 ] ;
fieldIds10 [ 0 ] = 1;
Object tmp11 =
(incoming).getValueAccessorById(NullableBigIntVector.class,
fieldIds10).getValueVector();
if (tmp11 == null) {
throw new SchemaChangeException("Failure while loading vector
vv9 with id: TypedFieldId [fieldIds=[1], remainder=null].");
}
vv9 = ((NullableBigIntVector) tmp11);
int[] fieldIds14 = new int[ 1 ] ;
fieldIds14 [ 0 ] = 0;
Object tmp15 =
(outgoing).getValueAccessorById(NullableBigIntVector.class,
fieldIds14).getValueVector();
if (tmp15 == null) {
throw new SchemaChangeException("Failure while loading vector
vv13 with id: TypedFieldId [fieldIds=[0], remainder=null].");
}
vv13 = ((NullableBigIntVector) tmp15);
/** start SETUP for function castBIGINT **/
{
IntHolder in = const17;
CastIntBigInt_setup:
{}
}
/** end SETUP for function castBIGINT **/
//---- start of eval portion of castBIGINT function. ----//
BigIntHolder out18 = new BigIntHolder();
{
final BigIntHolder out = new BigIntHolder();
IntHolder in = const17;
CastIntBigInt_eval:
{
out.value = in.value;
}
out18 = out;
}
//---- end of eval portion of castBIGINT function. ----//
constant19 = out18;
/** start SETUP for function equal **/
{
BigIntHolder right = constant19;
GCompareBigIntVsBigInt$EqualsBigIntVsBigInt_setup:
{}
}
/** end SETUP for function equal **/
int[] fieldIds22 = new int[ 1 ] ;
fieldIds22 [ 0 ] = 1;
Object tmp23 =
(incoming).getValueAccessorById(NullableBigIntVector.class,
fieldIds22).getValueVector();
if (tmp23 == null) {
throw new SchemaChangeException("Failure while loading vector
vv21 with id: TypedFieldId [fieldIds=[1], remainder=null].");
}
vv21 = ((NullableBigIntVector) tmp23);
int[] fieldIds26 = new int[ 1 ] ;
fieldIds26 [ 0 ] = 1;
Object tmp27 =
(outgoing).getValueAccessorById(NullableBigIntVector.class,
fieldIds26).getValueVector();
if (tmp27 == null) {
throw new SchemaChangeException("Failure while loading vector
vv25 with id: TypedFieldId [fieldIds=[1], remainder=null].");
}
vv25 = ((NullableBigIntVector) tmp27);
}
}
public void __DRILL_INIT__()
throws SchemaChangeException
{
}
}
{code}
The same class after scalar replacement \[1\] (without changes in this PR, so
it is incorrect):
{code:java}
package org.apache.drill.exec.test.generated;
import java.util.List;
import org.apache.drill.exec.exception.SchemaChangeException;
import org.apache.drill.exec.expr.holders.BigIntHolder;
import org.apache.drill.exec.expr.holders.IntHolder;
import org.apache.drill.exec.ops.FragmentContext;
import org.apache.drill.exec.physical.impl.project.Projector;
import org.apache.drill.exec.record.RecordBatch;
import org.apache.drill.exec.record.TransferPair;
import org.apache.drill.exec.record.BatchSchema.SelectionVectorMode;
import org.apache.drill.exec.record.selection.SelectionVector2;
import org.apache.drill.exec.record.selection.SelectionVector4;
import org.apache.drill.exec.vector.NullableBigIntVector;
import org.apache.drill.shaded.guava.com.google.common.collect.ImmutableList;
import
org.apache.drill.shaded.guava.com.google.common.collect.UnmodifiableIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class ProjectorGen0 implements Projector {
static final Logger logger = LoggerFactory.getLogger(ProjectorGen0.class);
private ImmutableList<TransferPair> transfers;
private SelectionVector2 vector2;
private SelectionVector4 vector4;
private SelectionVectorMode svMode;
NullableBigIntVector vv1;
IntHolder const5;
BigIntHolder constant7;
NullableBigIntVector vv9;
NullableBigIntVector vv13;
IntHolder const17;
BigIntHolder constant19;
NullableBigIntVector vv21;
NullableBigIntVector vv25;
static Class class$org$apache$drill$exec$vector$NullableBigIntVector;
public ProjectorGen0() {
this.__DRILL_INIT__();
}
public final int projectRecords(RecordBatch incomingRecordBatch, int
startIndex, int recordCount, int firstOutputIndex) {
assert incomingRecordBatch != this;
int i;
switch(this.svMode) {
case FOUR_BYTE:
throw new UnsupportedOperationException();
case TWO_BYTE:
int count = recordCount;
for(i = 0; i < count; ++firstOutputIndex) {
try {
this.doEval(this.vector2.getIndex(i), firstOutputIndex);
} catch (SchemaChangeException var12) {
throw new UnsupportedOperationException(var12);
}
++i;
}
return recordCount;
case NONE:
i = recordCount;
int i;
for(i = startIndex; i < startIndex + i; ++firstOutputIndex) {
try {
this.doEval(i, firstOutputIndex);
} catch (SchemaChangeException var11) {
throw new UnsupportedOperationException(var11);
}
++i;
}
int totalBatchRecordCount = incomingRecordBatch.getRecordCount();
UnmodifiableIterator var9;
TransferPair t;
if (startIndex + recordCount >= totalBatchRecordCount && startIndex <= 0)
{
var9 = this.transfers.iterator();
while(var9.hasNext()) {
t = (TransferPair)var9.next();
t.transfer();
}
return recordCount;
}
var9 = this.transfers.iterator();
while(var9.hasNext()) {
t = (TransferPair)var9.next();
t.splitAndTransfer(startIndex, i - startIndex);
}
return i - startIndex;
default:
throw new UnsupportedOperationException();
}
}
public final void setup(FragmentContext context, RecordBatch incoming,
RecordBatch outgoing, List<TransferPair> transfers) throws
SchemaChangeException {
this.svMode = incoming.getSchema().getSelectionVectorMode();
switch(this.svMode) {
case FOUR_BYTE:
this.vector4 = incoming.getSelectionVector4();
break;
case TWO_BYTE:
this.vector2 = incoming.getSelectionVector2();
}
this.transfers = ImmutableList.copyOf(transfers);
this.doSetup(context, incoming, outgoing);
}
public String toString() {
return "Projector[vector2=" + this.vector2 + ", selectionVectorMode=" +
this.svMode + "]";
}
public final void doEval(int inIndex, int outIndex) throws
SchemaChangeException {
int var3 = 0;
long var4 = 0L;
boolean var6 = false;
long var7 = 0L;
int var39 = this.vv1.getAccessor().isSet(inIndex);
if (var39 == 1) {
var7 = this.vv1.getAccessor().get(inIndex);
}
boolean var9 = false;
boolean var10 = false;
if (var39 == 0) {
var9 = false;
} else {
boolean var11 = false;
boolean var12 = false;
BigIntHolder right = this.constant7;
if (Double.isNaN((double)var7) && Double.isNaN((double)right.value)) {
var12 = true;
} else {
var12 = var7 == right.value;
}
var11 = true;
var10 = var12;
var9 = true;
}
if (var9 && var10) {
if (var39 != 0) {
var3 = var39;
var4 = var7;
}
} else {
boolean var14 = false;
long var15 = 0L;
int var40 = this.vv9.getAccessor().isSet(inIndex);
if (var40 == 1) {
var15 = this.vv9.getAccessor().get(inIndex);
}
if (var40 != 0) {
var3 = var40;
var4 = var15;
}
}
if (var3 != 0) {
this.vv13.getMutator().set(outIndex, var3, var4);
}
int var17 = 0;
long var18 = 0L;
boolean var20 = false;
boolean var21 = false;
if (var3 == 0) {
var20 = false;
} else {
boolean var22 = false;
boolean var23 = false;
BigIntHolder right = this.constant19;
if (Double.isNaN((double)var4) && Double.isNaN((double)right.value)) {
var23 = true;
} else {
var23 = var4 == right.value;
}
var22 = true;
var21 = var23;
var20 = true;
}
if (var20 && var21) {
if (var3 != 0) {
var17 = var3;
var18 = var4;
}
} else {
boolean var25 = false;
long var26 = 0L;
int var41 = this.vv21.getAccessor().isSet(inIndex);
if (var41 == 1) {
var26 = this.vv21.getAccessor().get(inIndex);
}
if (var41 != 0) {
var17 = var41;
var18 = var26;
}
}
if (var17 != 0) {
this.vv25.getMutator().set(outIndex, var17, var18);
}
}
public final void doSetup(FragmentContext context, RecordBatch incoming,
RecordBatch outgoing) throws SchemaChangeException {
int[] fieldIds2 = new int[]{0};
Object tmp3 =
incoming.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds2).getValueVector();
if (tmp3 == null) {
throw new SchemaChangeException("Failure while loading vector vv1 with
id: TypedFieldId [fieldIds=[0], remainder=null].");
} else {
this.vv1 = (NullableBigIntVector)tmp3;
IntHolder var6 = this.const5;
new BigIntHolder();
BigIntHolder out = new BigIntHolder();
IntHolder in = this.const5;
out.value = (long)in.value;
this.constant7 = out;
BigIntHolder var10 = this.constant7;
int[] fieldIds10 = new int[]{1};
Object tmp11 =
incoming.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds10).getValueVector();
if (tmp11 == null) {
throw new SchemaChangeException("Failure while loading vector vv9 with
id: TypedFieldId [fieldIds=[1], remainder=null].");
} else {
this.vv9 = (NullableBigIntVector)tmp11;
int[] fieldIds14 = new int[]{0};
Object tmp15 =
outgoing.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds14).getValueVector();
if (tmp15 == null) {
throw new SchemaChangeException("Failure while loading vector vv13
with id: TypedFieldId [fieldIds=[0], remainder=null].");
} else {
this.vv13 = (NullableBigIntVector)tmp15;
IntHolder var15 = this.const17;
new BigIntHolder();
BigIntHolder out = new BigIntHolder();
IntHolder in = this.const17;
out.value = (long)in.value;
this.constant19 = out;
BigIntHolder var19 = this.constant19;
int[] fieldIds22 = new int[]{1};
Object tmp23 =
incoming.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds22).getValueVector();
if (tmp23 == null) {
throw new SchemaChangeException("Failure while loading vector vv21
with id: TypedFieldId [fieldIds=[1], remainder=null].");
} else {
this.vv21 = (NullableBigIntVector)tmp23;
int[] fieldIds26 = new int[]{1};
Object tmp27 =
outgoing.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds26).getValueVector();
if (tmp27 == null) {
throw new SchemaChangeException("Failure while loading vector
vv25 with id: TypedFieldId [fieldIds=[1], remainder=null].");
} else {
this.vv25 = (NullableBigIntVector)tmp27;
}
}
}
}
}
}
public final void __DRILL_INIT__() throws SchemaChangeException {
}
static final Class class$(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException var2) {
throw new NoClassDefFoundError(var2.getMessage());
}
}
}
{code}
This class after scalar replacement but with changes in this PR:
{code:java}
package org.apache.drill.exec.test.generated;
import java.util.List;
import org.apache.drill.exec.exception.SchemaChangeException;
import org.apache.drill.exec.expr.holders.BigIntHolder;
import org.apache.drill.exec.expr.holders.IntHolder;
import org.apache.drill.exec.expr.holders.NullableBigIntHolder;
import org.apache.drill.exec.expr.holders.NullableBitHolder;
import org.apache.drill.exec.ops.FragmentContext;
import org.apache.drill.exec.physical.impl.project.Projector;
import org.apache.drill.exec.record.RecordBatch;
import org.apache.drill.exec.record.TransferPair;
import org.apache.drill.exec.record.BatchSchema.SelectionVectorMode;
import org.apache.drill.exec.record.selection.SelectionVector2;
import org.apache.drill.exec.record.selection.SelectionVector4;
import org.apache.drill.exec.vector.NullableBigIntVector;
import org.apache.drill.shaded.guava.com.google.common.collect.ImmutableList;
import
org.apache.drill.shaded.guava.com.google.common.collect.UnmodifiableIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class ProjectorGen0 implements Projector {
static final Logger logger = LoggerFactory.getLogger(ProjectorGen0.class);
private ImmutableList<TransferPair> transfers;
private SelectionVector2 vector2;
private SelectionVector4 vector4;
private SelectionVectorMode svMode;
NullableBigIntVector vv1;
IntHolder const5;
BigIntHolder constant7;
NullableBigIntVector vv9;
NullableBigIntVector vv13;
IntHolder const17;
BigIntHolder constant19;
NullableBigIntVector vv21;
NullableBigIntVector vv25;
static Class class$org$apache$drill$exec$vector$NullableBigIntVector;
public ProjectorGen0() {
this.__DRILL_INIT__();
}
public final int projectRecords(RecordBatch incomingRecordBatch, int
startIndex, int recordCount, int firstOutputIndex) {
assert incomingRecordBatch != this;
int i;
switch(this.svMode) {
case FOUR_BYTE:
throw new UnsupportedOperationException();
case TWO_BYTE:
int count = recordCount;
for(i = 0; i < count; ++firstOutputIndex) {
try {
this.doEval(this.vector2.getIndex(i), firstOutputIndex);
} catch (SchemaChangeException var12) {
throw new UnsupportedOperationException(var12);
}
++i;
}
return recordCount;
case NONE:
i = recordCount;
int i;
for(i = startIndex; i < startIndex + i; ++firstOutputIndex) {
try {
this.doEval(i, firstOutputIndex);
} catch (SchemaChangeException var11) {
throw new UnsupportedOperationException(var11);
}
++i;
}
int totalBatchRecordCount = incomingRecordBatch.getRecordCount();
UnmodifiableIterator var9;
TransferPair t;
if (startIndex + recordCount >= totalBatchRecordCount && startIndex <= 0)
{
var9 = this.transfers.iterator();
while(var9.hasNext()) {
t = (TransferPair)var9.next();
t.transfer();
}
return recordCount;
}
var9 = this.transfers.iterator();
while(var9.hasNext()) {
t = (TransferPair)var9.next();
t.splitAndTransfer(startIndex, i - startIndex);
}
return i - startIndex;
default:
throw new UnsupportedOperationException();
}
}
public final void setup(FragmentContext context, RecordBatch incoming,
RecordBatch outgoing, List<TransferPair> transfers) throws
SchemaChangeException {
this.svMode = incoming.getSchema().getSelectionVectorMode();
switch(this.svMode) {
case FOUR_BYTE:
this.vector4 = incoming.getSelectionVector4();
break;
case TWO_BYTE:
this.vector2 = incoming.getSelectionVector2();
}
this.transfers = ImmutableList.copyOf(transfers);
this.doSetup(context, incoming, outgoing);
}
public String toString() {
return "Projector[vector2=" + this.vector2 + ", selectionVectorMode=" +
this.svMode + "]";
}
public final void doEval(int inIndex, int outIndex) throws
SchemaChangeException {
NullableBigIntHolder out0 = new NullableBigIntHolder();
NullableBigIntHolder out4 = new NullableBigIntHolder();
out4.isSet = this.vv1.getAccessor().isSet(inIndex);
if (out4.isSet == 1) {
out4.value = this.vv1.getAccessor().get(inIndex);
}
NullableBitHolder out8 = new NullableBitHolder();
if (out4.isSet == 0) {
out8.isSet = 0;
} else {
NullableBitHolder out = new NullableBitHolder();
BigIntHolder right = this.constant7;
if (Double.isNaN((double)out4.value) &&
Double.isNaN((double)right.value)) {
out.value = 1;
} else {
out.value = out4.value == right.value ? 1 : 0;
}
out.isSet = 1;
out8 = out;
out.isSet = 1;
}
if (out8.isSet == 1 && out8.value == 1) {
if (out4.isSet != 0) {
out0 = out4;
}
} else {
NullableBigIntHolder out12 = new NullableBigIntHolder();
out12.isSet = this.vv9.getAccessor().isSet(inIndex);
if (out12.isSet == 1) {
out12.value = this.vv9.getAccessor().get(inIndex);
}
if (out12.isSet != 0) {
out0 = out12;
}
}
if (out0.isSet != 0) {
this.vv13.getMutator().set(outIndex, out0.isSet, out0.value);
}
NullableBigIntHolder out16 = new NullableBigIntHolder();
NullableBitHolder out20 = new NullableBitHolder();
if (out4.isSet == 0) {
out20.isSet = 0;
} else {
NullableBitHolder out = new NullableBitHolder();
BigIntHolder right = this.constant19;
if (Double.isNaN((double)out4.value) &&
Double.isNaN((double)right.value)) {
out.value = 1;
} else {
out.value = out4.value == right.value ? 1 : 0;
}
out.isSet = 1;
out20 = out;
out.isSet = 1;
}
if (out20.isSet == 1 && out20.value == 1) {
if (out4.isSet != 0) {
out16 = out4;
}
} else {
NullableBigIntHolder out24 = new NullableBigIntHolder();
out24.isSet = this.vv21.getAccessor().isSet(inIndex);
if (out24.isSet == 1) {
out24.value = this.vv21.getAccessor().get(inIndex);
}
if (out24.isSet != 0) {
out16 = out24;
}
}
if (out16.isSet != 0) {
this.vv25.getMutator().set(outIndex, out16.isSet, out16.value);
}
}
public final void doSetup(FragmentContext context, RecordBatch incoming,
RecordBatch outgoing) throws SchemaChangeException {
int[] fieldIds2 = new int[]{0};
Object tmp3 =
incoming.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds2).getValueVector();
if (tmp3 == null) {
throw new SchemaChangeException("Failure while loading vector vv1 with
id: TypedFieldId [fieldIds=[0], remainder=null].");
} else {
this.vv1 = (NullableBigIntVector)tmp3;
IntHolder var6 = this.const5;
new BigIntHolder();
BigIntHolder out = new BigIntHolder();
IntHolder in = this.const5;
out.value = (long)in.value;
this.constant7 = out;
BigIntHolder var10 = this.constant7;
int[] fieldIds10 = new int[]{1};
Object tmp11 =
incoming.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds10).getValueVector();
if (tmp11 == null) {
throw new SchemaChangeException("Failure while loading vector vv9 with
id: TypedFieldId [fieldIds=[1], remainder=null].");
} else {
this.vv9 = (NullableBigIntVector)tmp11;
int[] fieldIds14 = new int[]{0};
Object tmp15 =
outgoing.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds14).getValueVector();
if (tmp15 == null) {
throw new SchemaChangeException("Failure while loading vector vv13
with id: TypedFieldId [fieldIds=[0], remainder=null].");
} else {
this.vv13 = (NullableBigIntVector)tmp15;
IntHolder var15 = this.const17;
new BigIntHolder();
BigIntHolder out = new BigIntHolder();
IntHolder in = this.const17;
out.value = (long)in.value;
this.constant19 = out;
BigIntHolder var19 = this.constant19;
int[] fieldIds22 = new int[]{1};
Object tmp23 =
incoming.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds22).getValueVector();
if (tmp23 == null) {
throw new SchemaChangeException("Failure while loading vector vv21
with id: TypedFieldId [fieldIds=[1], remainder=null].");
} else {
this.vv21 = (NullableBigIntVector)tmp23;
int[] fieldIds26 = new int[]{1};
Object tmp27 =
outgoing.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds26).getValueVector();
if (tmp27 == null) {
throw new SchemaChangeException("Failure while loading vector
vv25 with id: TypedFieldId [fieldIds=[1], remainder=null].");
} else {
this.vv25 = (NullableBigIntVector)tmp27;
}
}
}
}
}
}
public final void __DRILL_INIT__() throws SchemaChangeException {
}
static final Class class$(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException var2) {
throw new NoClassDefFoundError(var2.getMessage());
}
}
}
{code}
Generated class for the query above but with changes in this PR (second commit):
{code:java}
package org.apache.drill.exec.test.generated;
import org.apache.drill.exec.exception.SchemaChangeException;
import org.apache.drill.exec.expr.holders.BigIntHolder;
import org.apache.drill.exec.expr.holders.IntHolder;
import org.apache.drill.exec.expr.holders.NullableBigIntHolder;
import org.apache.drill.exec.expr.holders.NullableBitHolder;
import org.apache.drill.exec.ops.FragmentContext;
import org.apache.drill.exec.physical.impl.project.ProjectorTemplate;
import org.apache.drill.exec.record.RecordBatch;
import org.apache.drill.exec.vector.NullableBigIntVector;
public class ProjectorGen0
extends ProjectorTemplate
{
NullableBigIntVector vv1;
IntHolder const5;
BigIntHolder constant7;
NullableBigIntVector vv9;
NullableBigIntVector vv13;
IntHolder const17;
BigIntHolder constant19;
NullableBigIntVector vv21;
NullableBigIntVector vv25;
public ProjectorGen0() {
try {
__DRILL_INIT__();
} catch (SchemaChangeException e) {
throw new UnsupportedOperationException(e);
}
}
public void doEval(int inIndex, int outIndex)
throws SchemaChangeException
{
{
NullableBigIntHolder out0 = new NullableBigIntHolder();
NullableBigIntHolder out4 = new NullableBigIntHolder();
{
out4 .isSet = vv1 .getAccessor().isSet((inIndex));
if (out4 .isSet == 1) {
out4 .value = vv1 .getAccessor().get((inIndex));
}
}
//---- start of eval portion of equal function. ----//
NullableBitHolder out8 = new NullableBitHolder();
{
if (out4 .isSet == 0) {
out8 .isSet = 0;
} else {
final NullableBitHolder out = new NullableBitHolder();
NullableBigIntHolder left = out4;
BigIntHolder right = constant7;
GCompareBigIntVsBigInt$EqualsBigIntVsBigInt_eval:
{
if (Double.isNaN(left.value) && Double.isNaN(right.value)) {
out.value = 1;
} else
{
out.value = left.value == right.value ? 1 : 0;
}
}
out8 .isSet = out.isSet;
out8 .value = out.value;
out8 .isSet = 1;
}
}
//---- end of eval portion of equal function. ----//
if ((out8 .isSet == 1)&&(out8 .value == 1)) {
if (out4 .isSet!= 0) {
out0 .isSet = out4 .isSet;
out0 .value = out4 .value;
}
} else {
NullableBigIntHolder out12 = new NullableBigIntHolder();
{
out12 .isSet = vv9 .getAccessor().isSet((inIndex));
if (out12 .isSet == 1) {
out12 .value = vv9 .getAccessor().get((inIndex));
}
}
if (out12 .isSet!= 0) {
out0 .isSet = out12 .isSet;
out0 .value = out12 .value;
}
}
if (!(out0 .isSet == 0)) {
vv13 .getMutator().set((outIndex), out0 .isSet, out0 .value);
}
NullableBigIntHolder out16 = new NullableBigIntHolder();
//---- start of eval portion of equal function. ----//
NullableBitHolder out20 = new NullableBitHolder();
{
if (out4 .isSet == 0) {
out20 .isSet = 0;
} else {
final NullableBitHolder out = new NullableBitHolder();
NullableBigIntHolder left = out4;
BigIntHolder right = constant19;
GCompareBigIntVsBigInt$EqualsBigIntVsBigInt_eval:
{
if (Double.isNaN(left.value) && Double.isNaN(right.value)) {
out.value = 1;
} else
{
out.value = left.value == right.value ? 1 : 0;
}
}
out20 .isSet = out.isSet;
out20 .value = out.value;
out20 .isSet = 1;
}
}
//---- end of eval portion of equal function. ----//
if ((out20 .isSet == 1)&&(out20 .value == 1)) {
if (out4 .isSet!= 0) {
out16 .isSet = out4 .isSet;
out16 .value = out4 .value;
}
} else {
NullableBigIntHolder out24 = new NullableBigIntHolder();
{
out24 .isSet = vv21 .getAccessor().isSet((inIndex));
if (out24 .isSet == 1) {
out24 .value = vv21 .getAccessor().get((inIndex));
}
}
if (out24 .isSet!= 0) {
out16 .isSet = out24 .isSet;
out16 .value = out24 .value;
}
}
if (!(out16 .isSet == 0)) {
vv25 .getMutator().set((outIndex), out16 .isSet, out16 .value);
}
}
}
public void doSetup(FragmentContext context, RecordBatch incoming,
RecordBatch outgoing)
throws SchemaChangeException
{
{
int[] fieldIds2 = new int[ 1 ] ;
fieldIds2 [ 0 ] = 0;
Object tmp3 =
(incoming).getValueAccessorById(NullableBigIntVector.class,
fieldIds2).getValueVector();
if (tmp3 == null) {
throw new SchemaChangeException("Failure while loading vector
vv1 with id: TypedFieldId [fieldIds=[0], remainder=null].");
}
vv1 = ((NullableBigIntVector) tmp3);
/** start SETUP for function castBIGINT **/
{
IntHolder in = const5;
CastIntBigInt_setup:
{}
}
/** end SETUP for function castBIGINT **/
//---- start of eval portion of castBIGINT function. ----//
BigIntHolder out6 = new BigIntHolder();
{
final BigIntHolder out = new BigIntHolder();
IntHolder in = const5;
CastIntBigInt_eval:
{
out.value = in.value;
}
out6 .value = out.value;
}
//---- end of eval portion of castBIGINT function. ----//
constant7 = new BigIntHolder();
constant7 .value = out6 .value;
/** start SETUP for function equal **/
{
BigIntHolder right = constant7;
GCompareBigIntVsBigInt$EqualsBigIntVsBigInt_setup:
{}
}
/** end SETUP for function equal **/
int[] fieldIds10 = new int[ 1 ] ;
fieldIds10 [ 0 ] = 1;
Object tmp11 =
(incoming).getValueAccessorById(NullableBigIntVector.class,
fieldIds10).getValueVector();
if (tmp11 == null) {
throw new SchemaChangeException("Failure while loading vector
vv9 with id: TypedFieldId [fieldIds=[1], remainder=null].");
}
vv9 = ((NullableBigIntVector) tmp11);
int[] fieldIds14 = new int[ 1 ] ;
fieldIds14 [ 0 ] = 0;
Object tmp15 =
(outgoing).getValueAccessorById(NullableBigIntVector.class,
fieldIds14).getValueVector();
if (tmp15 == null) {
throw new SchemaChangeException("Failure while loading vector
vv13 with id: TypedFieldId [fieldIds=[0], remainder=null].");
}
vv13 = ((NullableBigIntVector) tmp15);
/** start SETUP for function castBIGINT **/
{
IntHolder in = const17;
CastIntBigInt_setup:
{}
}
/** end SETUP for function castBIGINT **/
//---- start of eval portion of castBIGINT function. ----//
BigIntHolder out18 = new BigIntHolder();
{
final BigIntHolder out = new BigIntHolder();
IntHolder in = const17;
CastIntBigInt_eval:
{
out.value = in.value;
}
out18 .value = out.value;
}
//---- end of eval portion of castBIGINT function. ----//
constant19 = new BigIntHolder();
constant19 .value = out18 .value;
/** start SETUP for function equal **/
{
BigIntHolder right = constant19;
GCompareBigIntVsBigInt$EqualsBigIntVsBigInt_setup:
{}
}
/** end SETUP for function equal **/
int[] fieldIds22 = new int[ 1 ] ;
fieldIds22 [ 0 ] = 1;
Object tmp23 =
(incoming).getValueAccessorById(NullableBigIntVector.class,
fieldIds22).getValueVector();
if (tmp23 == null) {
throw new SchemaChangeException("Failure while loading vector
vv21 with id: TypedFieldId [fieldIds=[1], remainder=null].");
}
vv21 = ((NullableBigIntVector) tmp23);
int[] fieldIds26 = new int[ 1 ] ;
fieldIds26 [ 0 ] = 1;
Object tmp27 =
(outgoing).getValueAccessorById(NullableBigIntVector.class,
fieldIds26).getValueVector();
if (tmp27 == null) {
throw new SchemaChangeException("Failure while loading vector
vv25 with id: TypedFieldId [fieldIds=[1], remainder=null].");
}
vv25 = ((NullableBigIntVector) tmp27);
}
}
public void __DRILL_INIT__()
throws SchemaChangeException
{
}
}
{code}
This class after scalar replacement \[2\] :
{code:java}
package org.apache.drill.exec.test.generated;
import java.util.List;
import org.apache.drill.exec.exception.SchemaChangeException;
import org.apache.drill.exec.expr.holders.BigIntHolder;
import org.apache.drill.exec.expr.holders.IntHolder;
import org.apache.drill.exec.ops.FragmentContext;
import org.apache.drill.exec.physical.impl.project.Projector;
import org.apache.drill.exec.record.RecordBatch;
import org.apache.drill.exec.record.TransferPair;
import org.apache.drill.exec.record.BatchSchema.SelectionVectorMode;
import org.apache.drill.exec.record.selection.SelectionVector2;
import org.apache.drill.exec.record.selection.SelectionVector4;
import org.apache.drill.exec.vector.NullableBigIntVector;
import org.apache.drill.shaded.guava.com.google.common.collect.ImmutableList;
import
org.apache.drill.shaded.guava.com.google.common.collect.UnmodifiableIterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class ProjectorGen0 implements Projector {
static final Logger logger = LoggerFactory.getLogger(ProjectorGen0.class);
private ImmutableList<TransferPair> transfers;
private SelectionVector2 vector2;
private SelectionVector4 vector4;
private SelectionVectorMode svMode;
NullableBigIntVector vv1;
IntHolder const5;
BigIntHolder constant7;
NullableBigIntVector vv9;
NullableBigIntVector vv13;
IntHolder const17;
BigIntHolder constant19;
NullableBigIntVector vv21;
NullableBigIntVector vv25;
static Class class$org$apache$drill$exec$vector$NullableBigIntVector;
public ProjectorGen0() {
this.__DRILL_INIT__();
}
public final int projectRecords(RecordBatch incomingRecordBatch, int
startIndex, int recordCount, int firstOutputIndex) {
assert incomingRecordBatch != this;
int i;
switch(this.svMode) {
case FOUR_BYTE:
throw new UnsupportedOperationException();
case TWO_BYTE:
int count = recordCount;
for(i = 0; i < count; ++firstOutputIndex) {
try {
this.doEval(this.vector2.getIndex(i), firstOutputIndex);
} catch (SchemaChangeException var12) {
throw new UnsupportedOperationException(var12);
}
++i;
}
return recordCount;
case NONE:
i = recordCount;
int i;
for(i = startIndex; i < startIndex + i; ++firstOutputIndex) {
try {
this.doEval(i, firstOutputIndex);
} catch (SchemaChangeException var11) {
throw new UnsupportedOperationException(var11);
}
++i;
}
int totalBatchRecordCount = incomingRecordBatch.getRecordCount();
UnmodifiableIterator var9;
TransferPair t;
if (startIndex + recordCount >= totalBatchRecordCount && startIndex <= 0)
{
var9 = this.transfers.iterator();
while(var9.hasNext()) {
t = (TransferPair)var9.next();
t.transfer();
}
return recordCount;
}
var9 = this.transfers.iterator();
while(var9.hasNext()) {
t = (TransferPair)var9.next();
t.splitAndTransfer(startIndex, i - startIndex);
}
return i - startIndex;
default:
throw new UnsupportedOperationException();
}
}
public final void setup(FragmentContext context, RecordBatch incoming,
RecordBatch outgoing, List<TransferPair> transfers) throws
SchemaChangeException {
this.svMode = incoming.getSchema().getSelectionVectorMode();
switch(this.svMode) {
case FOUR_BYTE:
this.vector4 = incoming.getSelectionVector4();
break;
case TWO_BYTE:
this.vector2 = incoming.getSelectionVector2();
}
this.transfers = ImmutableList.copyOf(transfers);
this.doSetup(context, incoming, outgoing);
}
public String toString() {
return "Projector[vector2=" + this.vector2 + ", selectionVectorMode=" +
this.svMode + "]";
}
public final void doEval(int inIndex, int outIndex) throws
SchemaChangeException {
int var3 = 0;
long var4 = 0L;
boolean var6 = false;
long var7 = 0L;
int var39 = this.vv1.getAccessor().isSet(inIndex);
if (var39 == 1) {
var7 = this.vv1.getAccessor().get(inIndex);
}
boolean var9 = false;
boolean var10 = false;
if (var39 == 0) {
var9 = false;
} else {
boolean var11 = false;
boolean var12 = false;
BigIntHolder right = this.constant7;
if (Double.isNaN((double)var7) && Double.isNaN((double)right.value)) {
var12 = true;
} else {
var12 = var7 == right.value;
}
var10 = var12;
var9 = true;
}
if (var9 && var10) {
if (var39 != 0) {
var3 = var39;
var4 = var7;
}
} else {
boolean var14 = false;
long var15 = 0L;
int var40 = this.vv9.getAccessor().isSet(inIndex);
if (var40 == 1) {
var15 = this.vv9.getAccessor().get(inIndex);
}
if (var40 != 0) {
var3 = var40;
var4 = var15;
}
}
if (var3 != 0) {
this.vv13.getMutator().set(outIndex, var3, var4);
}
int var17 = 0;
long var18 = 0L;
boolean var20 = false;
boolean var21 = false;
if (var39 == 0) {
var20 = false;
} else {
boolean var22 = false;
boolean var23 = false;
BigIntHolder right = this.constant19;
if (Double.isNaN((double)var7) && Double.isNaN((double)right.value)) {
var23 = true;
} else {
var23 = var7 == right.value;
}
var21 = var23;
var20 = true;
}
if (var20 && var21) {
if (var39 != 0) {
var17 = var39;
var18 = var7;
}
} else {
boolean var25 = false;
long var26 = 0L;
int var41 = this.vv21.getAccessor().isSet(inIndex);
if (var41 == 1) {
var26 = this.vv21.getAccessor().get(inIndex);
}
if (var41 != 0) {
var17 = var41;
var18 = var26;
}
}
if (var17 != 0) {
this.vv25.getMutator().set(outIndex, var17, var18);
}
}
public final void doSetup(FragmentContext context, RecordBatch incoming,
RecordBatch outgoing) throws SchemaChangeException {
int[] fieldIds2 = new int[]{0};
Object tmp3 =
incoming.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds2).getValueVector();
if (tmp3 == null) {
throw new SchemaChangeException("Failure while loading vector vv1 with
id: TypedFieldId [fieldIds=[0], remainder=null].");
} else {
this.vv1 = (NullableBigIntVector)tmp3;
IntHolder var6 = this.const5;
long var7 = 0L;
long var9 = 0L;
IntHolder in = this.const5;
var9 = (long)in.value;
this.constant7 = new BigIntHolder();
this.constant7.value = var9;
BigIntHolder var12 = this.constant7;
int[] fieldIds10 = new int[]{1};
Object tmp11 =
incoming.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds10).getValueVector();
if (tmp11 == null) {
throw new SchemaChangeException("Failure while loading vector vv9 with
id: TypedFieldId [fieldIds=[1], remainder=null].");
} else {
this.vv9 = (NullableBigIntVector)tmp11;
int[] fieldIds14 = new int[]{0};
Object tmp15 =
outgoing.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds14).getValueVector();
if (tmp15 == null) {
throw new SchemaChangeException("Failure while loading vector vv13
with id: TypedFieldId [fieldIds=[0], remainder=null].");
} else {
this.vv13 = (NullableBigIntVector)tmp15;
IntHolder var17 = this.const17;
long var18 = 0L;
long var20 = 0L;
IntHolder in = this.const17;
var20 = (long)in.value;
this.constant19 = new BigIntHolder();
this.constant19.value = var20;
BigIntHolder var23 = this.constant19;
int[] fieldIds22 = new int[]{1};
Object tmp23 =
incoming.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds22).getValueVector();
if (tmp23 == null) {
throw new SchemaChangeException("Failure while loading vector vv21
with id: TypedFieldId [fieldIds=[1], remainder=null].");
} else {
this.vv21 = (NullableBigIntVector)tmp23;
int[] fieldIds26 = new int[]{1};
Object tmp27 =
outgoing.getValueAccessorById(class$org$apache$drill$exec$vector$NullableBigIntVector
!= null ? class$org$apache$drill$exec$vector$NullableBigIntVector :
(class$org$apache$drill$exec$vector$NullableBigIntVector =
class$("org.apache.drill.exec.vector.NullableBigIntVector")),
fieldIds26).getValueVector();
if (tmp27 == null) {
throw new SchemaChangeException("Failure while loading vector
vv25 with id: TypedFieldId [fieldIds=[1], remainder=null].");
} else {
this.vv25 = (NullableBigIntVector)tmp27;
}
}
}
}
}
}
public final void __DRILL_INIT__() throws SchemaChangeException {
}
static final Class class$(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException var2) {
throw new NoClassDefFoundError(var2.getMessage());
}
}
}
{code}
Please note that for target clases before the changes \[1\] and after the
changes \[2\], scalar replacement produced for almost all holders, but for the
second case the code is correct.
> Two CASE statements in projection influence results of each other
> -----------------------------------------------------------------
>
> Key: DRILL-6524
> URL: https://issues.apache.org/jira/browse/DRILL-6524
> Project: Apache Drill
> Issue Type: Bug
> Components: Query Planning & Optimization
> Affects Versions: 1.11.0
> Environment: Linux 3.10.0-693.21.1.el7.x86_64 #1 SMP Wed Mar 7
> 19:03:37 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux,
> NAME="CentOS Linux"
> VERSION="7 (Core)"
> apache drill 1.11.0,
> openjdk version "1.8.0_171"
> OpenJDK Runtime Environment (build 1.8.0_171-b10)
> OpenJDK 64-Bit Server VM (build 25.171-b10, mixed mode)
> Reporter: Oleksandr Chornyi
> Assignee: Volodymyr Vysotskyi
> Priority: Major
> Fix For: 1.16.0
>
>
> h3. Steps to Reproduce
> Run the following query via {{sqlline}}:
> {code:sql}
> select
> case when expr$0 = 3 then expr$0 else expr$1 end,
> case when expr$0 = 1 then expr$0 else expr$1 end
> from (values(1, 2));
> {code}
> h4. Actual Results
> {noformat}
> +---------+---------+
> | EXPR$0 | EXPR$1 |
> +---------+---------+
> | 2 | 2 |
> +---------+---------+
> {noformat}
> h4. Expected Results
> {noformat}
> +---------+---------+
> | EXPR$0 | EXPR$1 |
> +---------+---------+
> | 2 | 1 |
> +---------+---------+
> {noformat}
> Note, that changing order of CASE statements fixes the issue. The following
> query yields correct results:
> {code:sql}
> select
> case when expr$0 = 1 then expr$0 else expr$1 end,
> case when expr$0 = 3 then expr$0 else expr$1 end
> from (values(1, 2));
> {code}
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)