protected abstract void transformRecord()

in asterix-graphix/src/main/java/org/apache/asterix/graphix/function/prepare/AbstractElementPrepare.java [52:114]


    protected abstract void transformRecord(RecordConstructor schemaRecord, Expression inputExpr, Expression sourceExpr)
            throws CompilationException;

    @Override
    public Expression prepare(Expression sourceExpr, Expression inputExpr, GraphIdentifier graphIdentifier,
            ElementLookupTable elementLookupTable) throws CompilationException {
        this.elementLookupTable = elementLookupTable;
        this.graphIdentifier = graphIdentifier;

        // Transform our record expression.
        if (sourceExpr.getKind() == Expression.Kind.RECORD_CONSTRUCTOR_EXPRESSION) {
            RecordConstructor recordConstructor = (RecordConstructor) sourceExpr;
            List<FieldBinding> fieldBindingList = recordConstructor.getFbList();
            Optional<FieldBinding> schemaBinding = fieldBindingList.stream().filter(f -> {
                LiteralExpr fieldNameExpr = (LiteralExpr) f.getLeftExpr();
                StringLiteral fieldNameValue = (StringLiteral) fieldNameExpr.getValue();
                return fieldNameValue.getStringValue().equals(GRAPHIX_SCHEMA_IDENTIFIER.getValue());
            }).findFirst();

            if (schemaBinding.isPresent()) {
                // We have previously introduced schema detail into this expression. Add to our existing record.
                FieldBinding schemaRecordBinding = schemaBinding.get();
                RecordConstructor schemaRecord = (RecordConstructor) schemaRecordBinding.getRightExpr();
                transformRecord(schemaRecord, inputExpr, sourceExpr);

            } else {
                // We need to introduce a schema detail record.
                RecordConstructor schemaRecord = new RecordConstructor(new ArrayList<>());
                schemaRecord.addHint(GraphixSchemaAnnotation.INSTANCE);
                schemaRecord.setSourceLocation(sourceExpr.getSourceLocation());
                transformRecord(schemaRecord, inputExpr, sourceExpr);
                LiteralExpr fieldNameExpr = new LiteralExpr(new StringLiteral(GRAPHIX_SCHEMA_IDENTIFIER.getValue()));
                FieldBinding newFieldBinding = new FieldBinding(fieldNameExpr, schemaRecord);
                fieldBindingList.add(newFieldBinding);

            }
            return sourceExpr;

        } else if (sourceExpr.getKind() == Expression.Kind.CALL_EXPRESSION) {
            CallExpr callExpr = (CallExpr) sourceExpr;
            if (callExpr.findHint(GraphixSchemaAnnotation.class) == GraphixSchemaAnnotation.INSTANCE) {
                // We have a previously decorated Graphix CALL-EXPR. Add to this record.
                RecordConstructor schemaRecord = (RecordConstructor) callExpr.getExprList().get(2);
                transformRecord(schemaRecord, inputExpr, sourceExpr);
                return sourceExpr;
            }
        }

        // We have a non-record-constructor expression that we need to add a schema detail record to.
        FunctionSignature functionSignature = new FunctionSignature(BuiltinFunctions.RECORD_ADD);
        List<Expression> callExprArguments = new ArrayList<>();
        RecordConstructor schemaRecord = new RecordConstructor(new ArrayList<>());
        transformRecord(schemaRecord, inputExpr, sourceExpr);

        // Finalize our new decorated schema detail record.
        callExprArguments.add(sourceExpr);
        callExprArguments.add(new LiteralExpr(new StringLiteral(GRAPHIX_SCHEMA_IDENTIFIER.getValue())));
        callExprArguments.add(schemaRecord);
        CallExpr callExpr = new CallExpr(functionSignature, callExprArguments);
        callExpr.setSourceLocation(sourceExpr.getSourceLocation());
        callExpr.addHint(GraphixSchemaAnnotation.INSTANCE);
        return callExpr;
    }