ballerina-platform / ballerina-lang

The Ballerina Programming Language
https://ballerina.io/
Apache License 2.0
3.68k stars 752 forks source link

[Bug]: Cannot invoke "io.ballerina.runtime.internal.values.MapValue.get(Object)" because "entry" is null when using query expressions #43409

Open gimantha opened 1 month ago

gimantha commented 1 month ago

Description

Consider the code below.

type Period record {
    string date;
    SomeClass[] someClass;
};

type TimeData record {
    string date;
    string section;
    string sectionPercent;
    string sectionCode;
};

type SomeClass record {
    string section;
    string sectionPercent;
    string sectionCode;
};

type Metadata record {
    string section;
    string sectionCode;
};

type Result record {|
    string accountId;
    Metadata[] assetClassList;
    Period[] periods;
|};

function fn(string accountId, TimeData[] timeData) returns Result {
    Period[] periods = [];

    string[] distinctDates = from var item in timeData
        let var date = item.date
        group by date
        select date;

    foreach string date in distinctDates {
        SomeClass[] someClass = from var item in timeData
            where item.date == date
            let var section = item.section
            let var sectionCode = item.section
            let var sectionPercent = item.sectionPercent
            group by section, sectionCode, sectionPercent
            select {section, sectionCode, sectionPercent};
        Period period = {
            date: date,
            someClass
        };
        periods.push(period);
    }

    Metadata[] metadata = from var item in timeData
        let var section = item.section
        let var sectionCode = item.sectionCode
        group by section, sectionCode
        select {section, sectionCode};

    return {
        accountId: accountId,
        assetClassList: metadata,
        periods: periods
    };
}

function fnC(string accountId, TimeData[] timeData) {
    future<Result>[] frs = [];

    foreach int i in 0 ... 100 {
        future<Result> fr = start fn(accountId, timeData);
        frs.push(fr);
    }

    foreach future<Result> item in frs {
        Result|error res = wait item;
    }
}

public function main() {
    future<()>[] frs = [];
    TimeData[] td = from int i in 1000 ... 2000
        let var val = i.toString()
        select {
            date: val,
            sectionPercent: val,
            sectionCode: val,
            section: val
        };

    foreach int i in 1000 ... 2000 {
        future<()> fr = start fnC(i.toString(), td);
        frs.push(fr);
    }

    foreach future<()> item in frs {
        error? unionResult = wait item;
    }
}

When running the above code, the following exception is thrown.

[2024-09-11 22:55:34,335] SEVERE {b7a.log.crash} - Cannot invoke "io.ballerina.runtime.internal.values.MapValue.get(Object)" because "entry" is null
java.lang.NullPointerException: Cannot invoke "io.ballerina.runtime.internal.values.MapValue.get(Object)" because "entry" is null
        at ballerina.lang&0046query.0.$value$_GroupByFunction.convertToStream(types.bal:694)
        at ballerina.lang&0046query.0.$value$_GroupByFunction.call(types.bal)
        at ballerina.lang&0046query.0.$value$_GroupByFunction.process(types.bal:665)
        at ballerina.lang&0046query.0.$value$_GroupByFunction.call(types.bal)
        at ballerina.lang&0046query.0.$value$_SelectFunction.process(types.bal:783)
        at ballerina.lang&0046query.0.$value$_SelectFunction.call(types.bal)
        at ballerina.lang&0046query.0.types.$gen$$anon$method$delegate$_StreamFunction&0046process$0(types.bal:93)
        at ballerina.lang&0046query.0.$value$_StreamPipeline.$gen$$anon$method$delegate$_StreamFunction&0046process$0$lambda0$(types.bal)
        at io.ballerina.runtime.internal.scheduling.SchedulerItem.execute(SchedulerItem.java:54)
        at io.ballerina.runtime.internal.scheduling.Scheduler.run(Scheduler.java:320)
        at io.ballerina.runtime.internal.scheduling.Scheduler.runSafely(Scheduler.java:287)
        at java.base/java.lang.Thread.run(Thread.java:833)

error: java.lang.NullPointerException: Cannot invoke "io.ballerina.runtime.internal.values.MapValue.get(Object)" because "entry" is null
        at ballerina.lang.query.0._GroupByFunction:convertToStream(types.bal:694)
           ballerina.lang.query.0._GroupByFunction:process(types.bal:665)
           ballerina.lang.query.0._SelectFunction:process(types.bal:783)
           ballerina.lang.query.0:$anon$method$delegate$_StreamFunction.process$0(types.bal:93)

Steps to Reproduce

No response

Affected Version(s)

2201.8.x, 2201.9.x, 2201.10.x

OS, DB, other environment details and versions

No response

Related area

-> Runtime

Related issue(s) (optional)

No response

Suggested label(s) (optional)

No response

Suggested assignee(s) (optional)

No response

gimantha commented 1 month ago

This issue will be fixed once https://github.com/ballerina-platform/ballerina-lang/pull/43353 is merged into master