List<RowExpression> projections,
DynamicClassLoader classLoader)
{
CallSiteBinder callSiteBinder = new CallSiteBinder();
ClassDefinition classDefinition = new ClassDefinition(new CompilerContext(BOOTSTRAP_METHOD),
a(PUBLIC, FINAL),
typeFromPathName("ScanFilterAndProjectOperator_" + CLASS_ID.incrementAndGet()),
type(AbstractScanFilterAndProjectOperator.class));
// declare fields
FieldDefinition sessionField = classDefinition.declareField(a(PRIVATE, FINAL), "session", ConnectorSession.class);
classDefinition.declareField(a(PRIVATE, VOLATILE, STATIC), CALL_SITES_FIELD_NAME, Map.class);
// constructor
classDefinition.declareConstructor(new CompilerContext(BOOTSTRAP_METHOD),
a(PUBLIC),
arg("operatorContext", OperatorContext.class),
arg("sourceId", PlanNodeId.class),
arg("dataStreamProvider", DataStreamProvider.class),
arg("columns", type(Iterable.class, ColumnHandle.class)),
arg("types", type(Iterable.class, Type.class)))
.getBody()
.comment("super(operatorContext, sourceId, dataStreamProvider, columns, types);")
.pushThis()
.getVariable("operatorContext")
.getVariable("sourceId")
.getVariable("dataStreamProvider")
.getVariable("columns")
.getVariable("types")
.invokeConstructor(AbstractScanFilterAndProjectOperator.class, OperatorContext.class, PlanNodeId.class, DataStreamProvider.class, Iterable.class, Iterable.class)
.comment("this.session = operatorContext.getSession();")
.pushThis()
.getVariable("operatorContext")
.invokeVirtual(OperatorContext.class, "getSession", ConnectorSession.class)
.putField(sessionField)
.ret();
generateFilterAndProjectRowOriented(classDefinition, filter, projections);
generateFilterAndProjectCursorMethod(classDefinition, projections);
//
// filter method
//
generateFilterMethod(callSiteBinder, classDefinition, filter, true);
generateFilterMethod(callSiteBinder, classDefinition, filter, false);
//
// project methods
//
List<Type> types = new ArrayList<>();
int projectionIndex = 0;
for (RowExpression projection : projections) {
generateProjectMethod(callSiteBinder, classDefinition, "project_" + projectionIndex, projection, true);
generateProjectMethod(callSiteBinder, classDefinition, "project_" + projectionIndex, projection, false);
types.add(projection.getType());
projectionIndex++;
}
//
// toString method
//
generateToString(
classDefinition,
toStringHelper(classDefinition.getType().getJavaClassName())
.add("filter", filter)
.add("projections", projections)
.toString());
Class<? extends SourceOperator> filterAndProjectClass = defineClass(classDefinition, SourceOperator.class, classLoader);