You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by GitBox <gi...@apache.org> on 2022/02/15 22:56:30 UTC

[GitHub] [pinot] Jackie-Jiang commented on a change in pull request #8204: reduce allocation rate in LookupTransformFunction

Jackie-Jiang commented on a change in pull request #8204:
URL: https://github.com/apache/pinot/pull/8204#discussion_r807383598



##########
File path: pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/LookupTransformFunction.java
##########
@@ -143,191 +153,251 @@ public TransformResultMetadata getResultMetadata() {
         _lookupColumnFieldSpec.isSingleValueField(), false);
   }
 
-  private Object[] lookup(ProjectionBlock projectionBlock) {
+  @FunctionalInterface
+  private interface ValueAcceptor {
+    void accept(int index, Object value);
+  }
+
+  private void lookup(ProjectionBlock projectionBlock, ValueAcceptor valueAcceptor) {
     int numPkColumns = _joinKeys.size();
     int numDocuments = projectionBlock.getNumDocs();
-    Object[][] pkColumns = new Object[numPkColumns][];
+    Object[] pkColumns = new Object[numPkColumns];
     for (int c = 0; c < numPkColumns; c++) {
       DataType storedType = _joinValueFieldSpecs.get(c).getDataType().getStoredType();
       TransformFunction tf = _joinValueFunctions.get(c);
       switch (storedType) {
         case INT:
-          pkColumns[c] = ArrayUtils.toObject(tf.transformToIntValuesSV(projectionBlock));
+          pkColumns[c] = tf.transformToIntValuesSV(projectionBlock);
           break;
         case LONG:
-          pkColumns[c] = ArrayUtils.toObject(tf.transformToLongValuesSV(projectionBlock));
+          pkColumns[c] = tf.transformToLongValuesSV(projectionBlock);
           break;
         case FLOAT:
-          pkColumns[c] = ArrayUtils.toObject(tf.transformToFloatValuesSV(projectionBlock));
+          pkColumns[c] = tf.transformToFloatValuesSV(projectionBlock);
           break;
         case DOUBLE:
-          pkColumns[c] = ArrayUtils.toObject(tf.transformToDoubleValuesSV(projectionBlock));
+          pkColumns[c] = tf.transformToDoubleValuesSV(projectionBlock);
           break;
         case STRING:
           pkColumns[c] = tf.transformToStringValuesSV(projectionBlock);
           break;
         case BYTES:
-          byte[][] primitiveValues = tf.transformToBytesValuesSV(projectionBlock);
-          pkColumns[c] = new ByteArray[numDocuments];
-          for (int i = 0; i < numDocuments; i++) {
-            pkColumns[c][i] = new ByteArray(primitiveValues[i]);
-          }
+          pkColumns[c] = tf.transformToBytesValuesSV(projectionBlock);
           break;
         default:
           throw new IllegalStateException("Unknown column type for primary key");
       }
     }
 
-    Object[] resultSet = new Object[numDocuments];
     Object[] pkValues = new Object[numPkColumns];
+    PrimaryKey primaryKey = new PrimaryKey(pkValues);
     for (int i = 0; i < numDocuments; i++) {
       // prepare pk
       for (int c = 0; c < numPkColumns; c++) {
-        pkValues[c] = pkColumns[c][i];
+        if (pkColumns[c] instanceof int[]) {
+          pkValues[c] = ((int[]) pkColumns[c])[i];
+        } else if (pkColumns[c] instanceof long[]) {
+          pkValues[c] = ((long[]) pkColumns[c])[i];
+        } else if (pkColumns[c] instanceof String[]) {
+          pkValues[c] = ((String[]) pkColumns[c])[i];
+        } else if (pkColumns[c] instanceof float[]) {
+          pkValues[c] = ((float[]) pkColumns[c])[i];
+        } else if (pkColumns[c] instanceof double[]) {
+          pkValues[c] = ((double[]) pkColumns[c])[i];
+        } else if (pkColumns[c] instanceof byte[][]) {
+          pkValues[c] = new ByteArray(((byte[][]) pkColumns[c])[i]);
+        }
       }
       // lookup
-      GenericRow row = _dataManager.lookupRowByPrimaryKey(new PrimaryKey(pkValues));
-      if (row != null) {
-        resultSet[i] = row.getValue(_dimColumnName);
-      }
+      GenericRow row = _dataManager.lookupRowByPrimaryKey(primaryKey);
+      Object value = row == null ? null : row.getValue(_dimColumnName);
+      valueAcceptor.accept(i, value);
     }
-    return resultSet;
   }
 
   @Override
   public int[] transformToIntValuesSV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    int[] resultSet = new int[lookupObjects.length];
-    Arrays.fill(resultSet, ((Number) _lookupColumnFieldSpec.getDefaultNullValue()).intValue());
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = ((Number) lookupObjects[i]).intValue();
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_intValuesSV == null || _intValuesSV.length < numDocs) {
+      _intValuesSV = new int[numDocs];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setIntSV);
+    return _intValuesSV;
   }
 
   @Override
   public long[] transformToLongValuesSV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    long[] resultSet = new long[lookupObjects.length];
-    Arrays.fill(resultSet, ((Number) _lookupColumnFieldSpec.getDefaultNullValue()).longValue());
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = ((Number) lookupObjects[i]).longValue();
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_longValuesSV == null || _longValuesSV.length < numDocs) {
+      _longValuesSV = new long[numDocs];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setLongSV);
+    return _longValuesSV;
   }
 
   @Override
   public float[] transformToFloatValuesSV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    float[] resultSet = new float[lookupObjects.length];
-    Arrays.fill(resultSet, ((Number) _lookupColumnFieldSpec.getDefaultNullValue()).floatValue());
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = ((Number) lookupObjects[i]).floatValue();
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_floatValuesSV == null || _floatValuesSV.length < numDocs) {
+      _floatValuesSV = new float[numDocs];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setFloatSV);
+    return _floatValuesSV;
   }
 
   @Override
   public double[] transformToDoubleValuesSV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    double[] resultSet = new double[lookupObjects.length];
-    Arrays.fill(resultSet, ((Number) _lookupColumnFieldSpec.getDefaultNullValue()).doubleValue());
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = ((Number) lookupObjects[i]).doubleValue();
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_doubleValuesSV == null || _doubleValuesSV.length < numDocs) {
+      _doubleValuesSV = new double[numDocs];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setDoubleSV);
+    return _doubleValuesSV;
   }
 
   @Override
   public String[] transformToStringValuesSV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    String[] resultSet = new String[lookupObjects.length];
-    Arrays.fill(resultSet, _lookupColumnFieldSpec.getDefaultNullValueString());
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = lookupObjects[i].toString();
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_stringValuesSV == null || _stringValuesSV.length < numDocs) {
+      _stringValuesSV = new String[numDocs];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setStringSV);
+    return _stringValuesSV;
   }
 
   @Override
   public byte[][] transformToBytesValuesSV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    byte[][] resultSet = new byte[lookupObjects.length][0];
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = (byte[]) lookupObjects[i];
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_byteValuesSV == null || _byteValuesSV.length < numDocs) {
+      _byteValuesSV = new byte[numDocs][];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setBytesSV);
+    return _byteValuesSV;
   }
 
   @Override
   public int[][] transformToIntValuesMV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    int[][] resultSet = new int[lookupObjects.length][0];
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = (int[]) lookupObjects[i];
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_intValuesMV == null || _intValuesMV.length < numDocs) {
+      _intValuesMV = new int[numDocs][];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setIntMV);
+    return _intValuesMV;
   }
 
   @Override
   public long[][] transformToLongValuesMV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    long[][] resultSet = new long[lookupObjects.length][0];
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = (long[]) lookupObjects[i];
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_longValuesMV == null || _longValuesMV.length < numDocs) {
+      _longValuesMV = new long[numDocs][];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setLongMV);
+    return _longValuesMV;
   }
 
   @Override
   public float[][] transformToFloatValuesMV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    float[][] resultSet = new float[lookupObjects.length][0];
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = (float[]) lookupObjects[i];
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_floatValuesMV == null || _floatValuesMV.length < numDocs) {
+      _floatValuesMV = new float[numDocs][];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setFloatMV);
+    return _floatValuesMV;
   }
 
   @Override
   public double[][] transformToDoubleValuesMV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    double[][] resultSet = new double[lookupObjects.length][0];
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = (double[]) lookupObjects[i];
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_doubleValuesMV == null || _doubleValuesMV.length < numDocs) {
+      _doubleValuesMV = new double[numDocs][];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setDoubleMV);
+    return _doubleValuesMV;
   }
 
   @Override
   public String[][] transformToStringValuesMV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    String[][] resultSet = new String[lookupObjects.length][0];
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = (String[]) lookupObjects[i];
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_stringValuesMV == null || _stringValuesMV.length < numDocs) {
+      _stringValuesMV = new String[numDocs][];
+    }
+    lookup(projectionBlock, this::setStringMV);
+    return _stringValuesMV;
+  }
+
+  private void setIntSV(int index, Object value) {

Review comment:
       (minor) Let annotate value as `nullable`, same for other places

##########
File path: pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/LookupTransformFunction.java
##########
@@ -143,191 +153,251 @@ public TransformResultMetadata getResultMetadata() {
         _lookupColumnFieldSpec.isSingleValueField(), false);
   }
 
-  private Object[] lookup(ProjectionBlock projectionBlock) {
+  @FunctionalInterface
+  private interface ValueAcceptor {
+    void accept(int index, Object value);
+  }
+
+  private void lookup(ProjectionBlock projectionBlock, ValueAcceptor valueAcceptor) {
     int numPkColumns = _joinKeys.size();
     int numDocuments = projectionBlock.getNumDocs();
-    Object[][] pkColumns = new Object[numPkColumns][];
+    Object[] pkColumns = new Object[numPkColumns];
     for (int c = 0; c < numPkColumns; c++) {
       DataType storedType = _joinValueFieldSpecs.get(c).getDataType().getStoredType();
       TransformFunction tf = _joinValueFunctions.get(c);
       switch (storedType) {
         case INT:
-          pkColumns[c] = ArrayUtils.toObject(tf.transformToIntValuesSV(projectionBlock));
+          pkColumns[c] = tf.transformToIntValuesSV(projectionBlock);
           break;
         case LONG:
-          pkColumns[c] = ArrayUtils.toObject(tf.transformToLongValuesSV(projectionBlock));
+          pkColumns[c] = tf.transformToLongValuesSV(projectionBlock);
           break;
         case FLOAT:
-          pkColumns[c] = ArrayUtils.toObject(tf.transformToFloatValuesSV(projectionBlock));
+          pkColumns[c] = tf.transformToFloatValuesSV(projectionBlock);
           break;
         case DOUBLE:
-          pkColumns[c] = ArrayUtils.toObject(tf.transformToDoubleValuesSV(projectionBlock));
+          pkColumns[c] = tf.transformToDoubleValuesSV(projectionBlock);
           break;
         case STRING:
           pkColumns[c] = tf.transformToStringValuesSV(projectionBlock);
           break;
         case BYTES:
-          byte[][] primitiveValues = tf.transformToBytesValuesSV(projectionBlock);
-          pkColumns[c] = new ByteArray[numDocuments];
-          for (int i = 0; i < numDocuments; i++) {
-            pkColumns[c][i] = new ByteArray(primitiveValues[i]);
-          }
+          pkColumns[c] = tf.transformToBytesValuesSV(projectionBlock);
           break;
         default:
           throw new IllegalStateException("Unknown column type for primary key");
       }
     }
 
-    Object[] resultSet = new Object[numDocuments];
     Object[] pkValues = new Object[numPkColumns];
+    PrimaryKey primaryKey = new PrimaryKey(pkValues);
     for (int i = 0; i < numDocuments; i++) {
       // prepare pk
       for (int c = 0; c < numPkColumns; c++) {
-        pkValues[c] = pkColumns[c][i];
+        if (pkColumns[c] instanceof int[]) {
+          pkValues[c] = ((int[]) pkColumns[c])[i];
+        } else if (pkColumns[c] instanceof long[]) {
+          pkValues[c] = ((long[]) pkColumns[c])[i];
+        } else if (pkColumns[c] instanceof String[]) {
+          pkValues[c] = ((String[]) pkColumns[c])[i];
+        } else if (pkColumns[c] instanceof float[]) {
+          pkValues[c] = ((float[]) pkColumns[c])[i];
+        } else if (pkColumns[c] instanceof double[]) {
+          pkValues[c] = ((double[]) pkColumns[c])[i];
+        } else if (pkColumns[c] instanceof byte[][]) {
+          pkValues[c] = new ByteArray(((byte[][]) pkColumns[c])[i]);
+        }
       }
       // lookup
-      GenericRow row = _dataManager.lookupRowByPrimaryKey(new PrimaryKey(pkValues));
-      if (row != null) {
-        resultSet[i] = row.getValue(_dimColumnName);
-      }
+      GenericRow row = _dataManager.lookupRowByPrimaryKey(primaryKey);
+      Object value = row == null ? null : row.getValue(_dimColumnName);
+      valueAcceptor.accept(i, value);
     }
-    return resultSet;
   }
 
   @Override
   public int[] transformToIntValuesSV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    int[] resultSet = new int[lookupObjects.length];
-    Arrays.fill(resultSet, ((Number) _lookupColumnFieldSpec.getDefaultNullValue()).intValue());
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = ((Number) lookupObjects[i]).intValue();
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_intValuesSV == null || _intValuesSV.length < numDocs) {
+      _intValuesSV = new int[numDocs];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setIntSV);
+    return _intValuesSV;
   }
 
   @Override
   public long[] transformToLongValuesSV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    long[] resultSet = new long[lookupObjects.length];
-    Arrays.fill(resultSet, ((Number) _lookupColumnFieldSpec.getDefaultNullValue()).longValue());
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = ((Number) lookupObjects[i]).longValue();
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_longValuesSV == null || _longValuesSV.length < numDocs) {
+      _longValuesSV = new long[numDocs];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setLongSV);
+    return _longValuesSV;
   }
 
   @Override
   public float[] transformToFloatValuesSV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    float[] resultSet = new float[lookupObjects.length];
-    Arrays.fill(resultSet, ((Number) _lookupColumnFieldSpec.getDefaultNullValue()).floatValue());
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = ((Number) lookupObjects[i]).floatValue();
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_floatValuesSV == null || _floatValuesSV.length < numDocs) {
+      _floatValuesSV = new float[numDocs];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setFloatSV);
+    return _floatValuesSV;
   }
 
   @Override
   public double[] transformToDoubleValuesSV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    double[] resultSet = new double[lookupObjects.length];
-    Arrays.fill(resultSet, ((Number) _lookupColumnFieldSpec.getDefaultNullValue()).doubleValue());
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = ((Number) lookupObjects[i]).doubleValue();
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_doubleValuesSV == null || _doubleValuesSV.length < numDocs) {
+      _doubleValuesSV = new double[numDocs];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setDoubleSV);
+    return _doubleValuesSV;
   }
 
   @Override
   public String[] transformToStringValuesSV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    String[] resultSet = new String[lookupObjects.length];
-    Arrays.fill(resultSet, _lookupColumnFieldSpec.getDefaultNullValueString());
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = lookupObjects[i].toString();
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_stringValuesSV == null || _stringValuesSV.length < numDocs) {
+      _stringValuesSV = new String[numDocs];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setStringSV);
+    return _stringValuesSV;
   }
 
   @Override
   public byte[][] transformToBytesValuesSV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    byte[][] resultSet = new byte[lookupObjects.length][0];
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = (byte[]) lookupObjects[i];
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_byteValuesSV == null || _byteValuesSV.length < numDocs) {
+      _byteValuesSV = new byte[numDocs][];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setBytesSV);
+    return _byteValuesSV;
   }
 
   @Override
   public int[][] transformToIntValuesMV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    int[][] resultSet = new int[lookupObjects.length][0];
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = (int[]) lookupObjects[i];
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_intValuesMV == null || _intValuesMV.length < numDocs) {
+      _intValuesMV = new int[numDocs][];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setIntMV);
+    return _intValuesMV;
   }
 
   @Override
   public long[][] transformToLongValuesMV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    long[][] resultSet = new long[lookupObjects.length][0];
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = (long[]) lookupObjects[i];
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_longValuesMV == null || _longValuesMV.length < numDocs) {
+      _longValuesMV = new long[numDocs][];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setLongMV);
+    return _longValuesMV;
   }
 
   @Override
   public float[][] transformToFloatValuesMV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    float[][] resultSet = new float[lookupObjects.length][0];
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = (float[]) lookupObjects[i];
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_floatValuesMV == null || _floatValuesMV.length < numDocs) {
+      _floatValuesMV = new float[numDocs][];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setFloatMV);
+    return _floatValuesMV;
   }
 
   @Override
   public double[][] transformToDoubleValuesMV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    double[][] resultSet = new double[lookupObjects.length][0];
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = (double[]) lookupObjects[i];
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_doubleValuesMV == null || _doubleValuesMV.length < numDocs) {
+      _doubleValuesMV = new double[numDocs][];
     }
-    return resultSet;
+    lookup(projectionBlock, this::setDoubleMV);
+    return _doubleValuesMV;
   }
 
   @Override
   public String[][] transformToStringValuesMV(ProjectionBlock projectionBlock) {
-    Object[] lookupObjects = lookup(projectionBlock);
-    String[][] resultSet = new String[lookupObjects.length][0];
-    for (int i = 0; i < lookupObjects.length; i++) {
-      if (lookupObjects[i] != null) {
-        resultSet[i] = (String[]) lookupObjects[i];
-      }
+    int numDocs = projectionBlock.getNumDocs();
+    if (_stringValuesMV == null || _stringValuesMV.length < numDocs) {
+      _stringValuesMV = new String[numDocs][];
+    }
+    lookup(projectionBlock, this::setStringMV);
+    return _stringValuesMV;
+  }
+
+  private void setIntSV(int index, Object value) {
+    if (value instanceof Number) {
+      _intValuesSV[index] = ((Number) value).intValue();
+    } else {
+      _intValuesSV[index] = _nullIntValue;
+    }
+  }
+
+  private void setLongSV(int index, Object value) {
+    if (value instanceof Number) {
+      _longValuesSV[index] = ((Number) value).longValue();
+    } else {
+      _longValuesSV[index] = _nullLongValue;
+    }
+  }
+
+  private void setFloatSV(int index, Object value) {
+    if (value instanceof Number) {
+      _floatValuesSV[index] = ((Number) value).floatValue();
+    } else {
+      _floatValuesSV[index] = _nullFloatValue;
+    }
+  }
+
+  private void setDoubleSV(int index, Object value) {
+    if (value instanceof Number) {
+      _doubleValuesSV[index] = ((Number) value).doubleValue();
+    } else {
+      _doubleValuesSV[index] = _nullDoubleValue;
+    }
+  }
+
+  private void setStringSV(int index, Object value) {
+    if (value != null) {
+      _stringValuesSV[index] = String.valueOf(value);
+    } else {
+      _stringValuesSV[index] = _lookupColumnFieldSpec.getDefaultNullValueString();
+    }
+  }
+
+  private void setBytesSV(int index, Object value) {
+    if (value instanceof byte[]) {
+      _byteValuesSV[index] = (byte[]) value;
+    }

Review comment:
       Since we didn't fill the default values, we need to put the default value here. Same for other methods without `else`




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org