<commit_before>package com.hazelcast.query.impl.predicates;

import com.hazelcast.config.Config;
import com.hazelcast.config.MapAttributeConfig;
import com.hazelcast.config.MapConfig;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import com.hazelcast.query.EntryObject;
import com.hazelcast.query.Predicate;
import com.hazelcast.query.PredicateBuilder;
import com.hazelcast.query.SqlPredicate;
import com.hazelcast.query.extractor.ValueCollector;
import com.hazelcast.query.extractor.ValueExtractor;
import com.hazelcast.test.HazelcastSerialClassRunner;
import com.hazelcast.test.HazelcastTestSupport;
import com.hazelcast.test.annotation.QuickTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;

import java.io.Serializable;
import java.util.Collection;

import static org.junit.Assert.assertEquals;

@RunWith(HazelcastSerialClassRunner.class)
@Category(QuickTest.class)
public class NestedPredicateWithExtractorTest extends HazelcastTestSupport {

    private HazelcastInstance instance;
    private IMap<Integer, Body> map;

    private static int bodyExtractorExecutions;
    private static int limbExtractorExecutions;

    public static class BodyNameExtractor extends ValueExtractor<Body, Object> {
        @Override
        public void extract(Body target, Object arguments, ValueCollector collector) {
            bodyExtractorExecutions++;
            collector.addObject(target.getName());
        }
    }

    public static class LimbNameExtractor extends ValueExtractor<Body, Object> {
        @Override
        public void extract(Body target, Object arguments, ValueCollector collector) {
            limbExtractorExecutions++;
            collector.addObject(target.getLimb().getName());
        }
    }

    @Before
    public void setup() {
        bodyExtractorExecutions = 0;
        limbExtractorExecutions = 0;
        Config config = new Config();
        MapConfig mapConfig = new MapConfig();
        mapConfig.setName("map");
        mapConfig.addMapAttributeConfig(extractor("name", "com.hazelcast.query.impl.predicates.NestedPredicateWithExtractorTest$BodyNameExtractor"));
        mapConfig.addMapAttributeConfig(extractor("limbname", "com.hazelcast.query.impl.predicates.NestedPredicateWithExtractorTest$LimbNameExtractor"));
        config.addMapConfig(mapConfig);
        instance = createHazelcastInstance(config);
        map = instance.getMap("map");
    }

    static MapAttributeConfig extractor(String name, String extractor) {
        MapAttributeConfig extractorConfig = new MapAttributeConfig();
        extractorConfig.setName(name);
        extractorConfig.setExtractor(extractor);
        return extractorConfig;
    }

    @Test
    public void singleAttributeQuery_predicates() throws Exception {
        // GIVEN
        map.put(1, new Body("body1", new Limb("hand")));
        map.put(2, new Body("body2", new Limb("leg")));

        // WHEN
        EntryObject e = new PredicateBuilder().getEntryObject();
        Predicate predicate = e.get("name").equal("body1");
        Collection<Body> values = map.values(predicate);

        // THEN
        assertEquals(1, values.size());
        assertEquals("body1", values.toArray(new Body[]{})[0].getName());
        assertEquals(2 + 1, bodyExtractorExecutions);
        assertEquals(0, limbExtractorExecutions);
    }

    @Test
    public void singleAttributeQuery_distributedSql() throws Exception {
        // GIVEN
        map.put(1, new Body("body1", new Limb("hand")));
        map.put(2, new Body("body2", new Limb("leg")));

        // WHEN
        Collection<Body> values = map.values(new SqlPredicate("name == 'body1'"));

        // THEN
        assertEquals(1, values.size());
        assertEquals("body1", values.toArray(new Body[]{})[0].getName());
        assertEquals(2 + 1, bodyExtractorExecutions);
        assertEquals(0, limbExtractorExecutions);
    }

    @Test
    public void nestedAttributeQuery_predicates() throws Exception {
        // GIVEN
        map.put(1, new Body("body1", new Limb("hand")));
        map.put(2, new Body("body2", new Limb("leg")));

        // WHEN
        EntryObject e = new PredicateBuilder().getEntryObject();
        Predicate predicate = e.get("limbname").equal("leg");
        Collection<Body> values = map.values(predicate);

        // THEN
        assertEquals(1, values.size());
        assertEquals("body2", values.toArray(new Body[]{})[0].getName());
        assertEquals(0, bodyExtractorExecutions);
        assertEquals(2 + 1, limbExtractorExecutions);
    }

    @Test
    public void nestedAttributeQuery_distributedSql() throws Exception {
        // GIVEN
        map.put(1, new Body("body1", new Limb("hand")));
        map.put(2, new Body("body2", new Limb("leg")));

        // WHEN
        Collection<Body> values = map.values(new SqlPredicate("limbname == 'leg'"));

        // THEN
        assertEquals(1, values.size());
        assertEquals("body2", values.toArray(new Body[]{})[0].getName());
        assertEquals(0, bodyExtractorExecutions);
        assertEquals(2 + 1, limbExtractorExecutions);
    }


    private static class Body implements Serializable {
        private final String name;
        private final Limb limb;

        public Body(String name, Limb limb) {
            this.name = name;
            this.limb = limb;<commit_msg>Extractors - new test case<commit_after>package com.hazelcast.query.impl.predicates;

import com.hazelcast.config.Config;
import com.hazelcast.config.MapAttributeConfig;
import com.hazelcast.config.MapConfig;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import com.hazelcast.map.EntryBackupProcessor;
import com.hazelcast.map.EntryProcessor;
import com.hazelcast.query.EntryObject;
import com.hazelcast.query.Predicate;
import com.hazelcast.query.PredicateBuilder;
import com.hazelcast.query.SqlPredicate;
import com.hazelcast.query.extractor.ValueCollector;
import com.hazelcast.query.extractor.ValueExtractor;
import com.hazelcast.query.impl.QueryableEntry;
import com.hazelcast.test.HazelcastSerialClassRunner;
import com.hazelcast.test.HazelcastTestSupport;
import com.hazelcast.test.annotation.QuickTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;

import java.io.Serializable;
import java.util.Collection;
import java.util.Map;

import static org.junit.Assert.assertEquals;

@RunWith(HazelcastSerialClassRunner.class)
@Category(QuickTest.class)
public class NestedPredicateWithExtractorTest extends HazelcastTestSupport {

    private HazelcastInstance instance;
    private IMap<Integer, Body> map;

    private static int bodyExtractorExecutions;
    private static int limbExtractorExecutions;

    public static class BodyNameExtractor extends ValueExtractor<Body, Object> {
        @Override
        public void extract(Body target, Object arguments, ValueCollector collector) {
            bodyExtractorExecutions++;
            collector.addObject(target.getName());
        }
    }

    public static class LimbNameExtractor extends ValueExtractor<Body, Object> {
        @Override
        public void extract(Body target, Object arguments, ValueCollector collector) {
            limbExtractorExecutions++;
            collector.addObject(target.getLimb().getName());
        }
    }

    @Before
    public void setup() {
        bodyExtractorExecutions = 0;
        limbExtractorExecutions = 0;
        Config config = new Config();
        MapConfig mapConfig = new MapConfig();
        mapConfig.setName("map");
        mapConfig.addMapAttributeConfig(extractor("name", "com.hazelcast.query.impl.predicates.NestedPredicateWithExtractorTest$BodyNameExtractor"));
        mapConfig.addMapAttributeConfig(extractor("limbname", "com.hazelcast.query.impl.predicates.NestedPredicateWithExtractorTest$LimbNameExtractor"));
        config.addMapConfig(mapConfig);
        instance = createHazelcastInstance(config);
        map = instance.getMap("map");
    }

    static MapAttributeConfig extractor(String name, String extractor) {
        MapAttributeConfig extractorConfig = new MapAttributeConfig();
        extractorConfig.setName(name);
        extractorConfig.setExtractor(extractor);
        return extractorConfig;
    }

    @Test
    public void singleAttributeQuery_predicates() throws Exception {
        // GIVEN
        map.put(1, new Body("body1", new Limb("hand")));
        map.put(2, new Body("body2", new Limb("leg")));

        // WHEN
        EntryObject e = new PredicateBuilder().getEntryObject();
        Predicate predicate = e.get("name").equal("body1");
        Collection<Body> values = map.values(predicate);

        // THEN
        assertEquals(1, values.size());
        assertEquals("body1", values.toArray(new Body[]{})[0].getName());
        assertEquals(2 + 1, bodyExtractorExecutions);
        assertEquals(0, limbExtractorExecutions);
    }

    @Test
    public void singleAttributeQuery_distributedSql() throws Exception {
        // GIVEN
        map.put(1, new Body("body1", new Limb("hand")));
        map.put(2, new Body("body2", new Limb("leg")));

        // WHEN
        Collection<Body> values = map.values(new SqlPredicate("name == 'body1'"));

        // THEN
        assertEquals(1, values.size());
        assertEquals("body1", values.toArray(new Body[]{})[0].getName());
        assertEquals(2 + 1, bodyExtractorExecutions);
        assertEquals(0, limbExtractorExecutions);
    }

    @Test
    public void nestedAttributeQuery_predicates() throws Exception {
        // GIVEN
        map.put(1, new Body("body1", new Limb("hand")));
        map.put(2, new Body("body2", new Limb("leg")));

        // WHEN
        EntryObject e = new PredicateBuilder().getEntryObject();
        Predicate predicate = e.get("limbname").equal("leg");
        Collection<Body> values = map.values(predicate);

        // THEN
        assertEquals(1, values.size());
        assertEquals("body2", values.toArray(new Body[]{})[0].getName());
        assertEquals(0, bodyExtractorExecutions);
        assertEquals(2 + 1, limbExtractorExecutions);
    }

    @Test
    public void nestedAttributeQuery_customPredicates_entryProcessor() throws Exception {
        // GIVEN
        map.put(1, new Body("body1", new Limb("hand")));
        map.put(2, new Body("body2", new Limb("leg")));

        // WHEN
        Map<Integer, Object> result = map.executeOnEntries(new ExtractProcessor(), new CustomPredicate());
        Body resultBody = (Body) result.values().iterator().next();

        // THEN
        assertEquals(1, result.size());
        assertEquals("body1", resultBody.getName());
    }

    private static final class ExtractProcessor implements EntryProcessor<Integer, Body> {
        @Override
        public Body process(Map.Entry<Integer, Body> entry) {
            return entry.getValue();
        }

        @Override
        public EntryBackupProcessor<Integer, Body> getBackupProcessor() {
            return null;
        }
    }

    private static final class CustomPredicate extends AbstractPredicate {
        public CustomPredicate() {
            super("limbname");
        }

        @Override
        protected boolean applyForSingleAttributeValue(Map.Entry mapEntry, Comparable attributeValue) {
            QueryableEntry queryableEntry = (QueryableEntry) mapEntry;
            Object val = queryableEntry.getAttributeValue(attributeName);
            return val.equals("hand");
        }

        @Override
        public int getId() {
            return 0;
        }
    }


    @Test
    public void nestedAttributeQuery_distributedSql() throws Exception {
        // GIVEN
        map.put(1, new Body("body1", new Limb("hand")));
        map.put(2, new Body("body2", new Limb("leg")));

        // WHEN
        Collection<Body> values = map.values(new SqlPredicate("limbname == 'leg'"));

        // THEN
        assertEquals(1, values.size());
        assertEquals("body2", values.toArray(new Body[]{})[0].getName());
        assertEquals(0, bodyExtractorExecutions);
        assertEquals(2 + 1, limbExtractorExecutions);
    }

    private static class Body implements Serializable {
        private final String name;
        private final Limb limb;

        public Body(String name, Limb limb) {
            this.name = name;
            this.limb = limb;
{'fraction_non_alphanumeric': 0.1142948615335361, 'fraction_numerical': 0.007603649751880903, 'mean_word_length': 3.211324570273003, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1700095', 'n_tokens_mistral': 3563, 'n_tokens_neox': 3471, 'n_words': 723}