Author: chetanm
Date: Fri Feb 20 11:51:59 2015
New Revision: 1661099
URL: http://svn.apache.org/r1661099
Log:
OAK-2517 - Support IS NULL based property restrictions in LucenePropertyIndex
Merging revisions 1660676
Modified:
jackrabbit/oak/branches/1.0/ (props changed)
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/PropertyDefinition.java
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinitionTest.java
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/TestUtil.java
Propchange: jackrabbit/oak/branches/1.0/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Feb 20 11:51:59 2015
@@ -1,2 +1,2 @@
-/jackrabbit/oak/trunk:1584578,1584602,1584614,1584616,1584709,1584781,1584937,1585297,1585304-1585305,1585420,1585424,1585427,1585448,1585465,1585468,1585486,1585497,1585509,1585647,1585655-1585656,1585661,1585665-1585666,1585669-1585670,1585673,1585680,1585719,1585763,1585770,1585896,1585904,1585907,1585940,1585949,1585951,1585956,1585962-1585963,1586287,1586320,1586364,1586372,1586655,1586836,1587130,1587224,1587399,1587408,1587472,1587485,1587488,1587538,1587580,1587807,1588033,1588042,1588046,1588066,1588201,1589025,1589101,1589137,1589141,1589263,1589440,1589442,1589484,1589488,1589661,1589664,1589682,1589708,1589741,1589748,1589789,1589794,1589850,1589864,1590628,1590660,1590684,1590697,1590701,1590980,1590988,1591101,1591226,1591229,1591293,1591314,1591317,1591362,1591374,1591381,1591438,1591467,1591552,1591704,1591713,1591715,1591723,1591874,1592487,1592512,1592658,1592665,1592677,1592742,1592744,1592787,1592809,1592955,1593036,1593048,1593061,1593133,1593210-1593211,1593231
,1593245,1593250,1593294,1593304,1593317,1593342,1593554,1594158-1594164,1594166-1594167,1594169,1594237,1594800,1594808,1594835,1594888,1595147,1595457,1595856,1596241,1596474,1596534,1596844,1597569,1597795,1597854,1597860,1598292,1598302,1598352,1598369,1598595,1598631,1598696,1598732,1598797-1598798,1599299,1599332,1599416,1599434,1599671,1600088,1600935,1601309,1601388,1601578,1601649,1601676,1601757,1601768,1601814,1601833,1601838,1601853,1601878,1601888,1601922,1602156,1602170,1602174,1602179,1602183,1602201,1602207,1602227,1602256,1602261,1602342,1602796-1602797,1602800,1602809,1602853,1602872,1602914,1603155,1603307,1603401,1603441,1603748,1604166,1605030,1605036,1605038,1605292,1605447,1605526,1605670,1605725,1605831,1605852,1606077,1606079,1606087,1606638,1606641,1606644,1606708,1606711,1607031-1607032,1607077,1607127,1607141,1607152,1607185,1607196,1607331,1607362,1607366,1607392,1607526,1607557,1607664,1607737,1608560,1608731,1608783,1609064,1609081,1609165,1609214,1609
488,1610489,1610592,1610603,1610634,1610658,1610664,1611021,1611041,1611270,1611275,1611277,1611313,1611332,1611584,1612560,1612825,1612993,1613018,1613041,1614265,1614272,1614344-1614345,1614384-1614385,1614397,1614405-1614406,1614574,1614591,1614593,1614596,1614604,1614689,1614807,1614835,1614891,1615417-1615418,1616182,1616236,1616463,1616719,1617417,1617451,1617463,1617711,1618158,1618613,1618624,1618709,1619222,1619411,1619695,1619800,1619808,1619815,1619823-1619824,1620512,1620581,1620585,1620634,1620898,1620905,1621115,1621123-1621124,1621168,1621192,1621201,1621706,1621962,1622197,1622201,1622207,1622250,1622479,1623364,1623766,1623827,1623949,1623969,1623973,1624216,1624317,1624551,1624559,1624973,1624993-1624994,1625025,1625036,1625158,1625224,1625237,1625299,1625348,1625620,1625916,1625962-1625963,1626021,1626053,1626163,1626168,1626175,1626191,1626265,1626770,1627047,1627052,1627228,1627346,1627470,1627473,1627479,1627503,1627586,1627590,1627715,1627731,1628180,1628198,1
628262,1628447,1628608,1629688,1629840,1629917,1630055-1630057,1630156,1630299,1630338,1630773,1631283-1631284,1631333-1631334,1631617-1631619,1631630,1631699,1631704,1631711,1631967-1631969,1631986,1631990,1631999,1632002-1632003,1632017,1632258,1632264,1632270,1632293,1632303,1632592,1632605,1633315,1633559-1633560,1633562,1633567,1633571,1633598,1633608,1633641,1633687,1633697,1633768,1633783,1634505,1634513,1634774,1634779,1634781,1634792,1634803,1634814,1634816,1634838,1634841,1634852,1634864,1634896,1634898,1635044-1635045,1635060,1635077,1635089,1635102,1635108,1635218,1635387,1635435,1635518,1635563,1635586,1636336,1636348,1636505,1636585,1636799,1637368,1637382,1637413,1637651,1637815,1638779-1638783,1639260,1639577,1639622,1639963,1639966,1639973,1640134,1640143,1640555-1640556,1640694-1640695,1640715,1640722-1640723,1640728,1640863-1640872,1641340,1641350,1641352,1641541,1641596-1641599,1641601,1641662,1641671,1641695,1641771,1641802,1641811,1641950,1642031,1642056,164211
9,1642285,1642648,1642667,1642954,1642959,1643111,1643178,1643186,1643204,1643287,1643767,1643774,1643982,1644016,1644106,1644366,1644383,1644397-1644398,1644407,1644479,1644547,1644552,1644554,1644588,1644645,1644650,1644654,1644689,1644750,1645421,1645424,1645459,1645585,1645611,1645637,1645646,1645660-1645663,1645888,1645901,1645948,1645966,1645970-1645971,1646014,1646164,1646174,1646684,1649743,1649803,1650015,1650239,1650529,1650797,1651323,1651382,1651643,1651652,1651730,1651988-1651989,1651996,1652024,1652035,1652058-1652059,1652075,1652127,1652158,1652467,1652965,1652971,1653207,1653446,1653463,1653484,1653572,1653579,1653591,1653804,1653809,1653848-1653850,1653882,1654116,1654743,1654756,1654778,1655049,1655054-1655055,1655086,1655237,1655248,1655996,1656027,1656394,1656400,1656425,1656427,1656453,1656628,1657804,1658470,1659483,1659527,1659550,1659578,1659765,1660154-1660155,1660383,1660409,1660426,1660870,1660872,1660897,1661069
+/jackrabbit/oak/trunk:1584578,1584602,1584614,1584616,1584709,1584781,1584937,1585297,1585304-1585305,1585420,1585424,1585427,1585448,1585465,1585468,1585486,1585497,1585509,1585647,1585655-1585656,1585661,1585665-1585666,1585669-1585670,1585673,1585680,1585719,1585763,1585770,1585896,1585904,1585907,1585940,1585949,1585951,1585956,1585962-1585963,1586287,1586320,1586364,1586372,1586655,1586836,1587130,1587224,1587399,1587408,1587472,1587485,1587488,1587538,1587580,1587807,1588033,1588042,1588046,1588066,1588201,1589025,1589101,1589137,1589141,1589263,1589440,1589442,1589484,1589488,1589661,1589664,1589682,1589708,1589741,1589748,1589789,1589794,1589850,1589864,1590628,1590660,1590684,1590697,1590701,1590980,1590988,1591101,1591226,1591229,1591293,1591314,1591317,1591362,1591374,1591381,1591438,1591467,1591552,1591704,1591713,1591715,1591723,1591874,1592487,1592512,1592658,1592665,1592677,1592742,1592744,1592787,1592809,1592955,1593036,1593048,1593061,1593133,1593210-1593211,1593231
,1593245,1593250,1593294,1593304,1593317,1593342,1593554,1594158-1594164,1594166-1594167,1594169,1594237,1594800,1594808,1594835,1594888,1595147,1595457,1595856,1596241,1596474,1596534,1596844,1597569,1597795,1597854,1597860,1598292,1598302,1598352,1598369,1598595,1598631,1598696,1598732,1598797-1598798,1599299,1599332,1599416,1599434,1599671,1600088,1600935,1601309,1601388,1601578,1601649,1601676,1601757,1601768,1601814,1601833,1601838,1601853,1601878,1601888,1601922,1602156,1602170,1602174,1602179,1602183,1602201,1602207,1602227,1602256,1602261,1602342,1602796-1602797,1602800,1602809,1602853,1602872,1602914,1603155,1603307,1603401,1603441,1603748,1604166,1605030,1605036,1605038,1605292,1605447,1605526,1605670,1605725,1605831,1605852,1606077,1606079,1606087,1606638,1606641,1606644,1606708,1606711,1607031-1607032,1607077,1607127,1607141,1607152,1607185,1607196,1607331,1607362,1607366,1607392,1607526,1607557,1607664,1607737,1608560,1608731,1608783,1609064,1609081,1609165,1609214,1609
488,1610489,1610592,1610603,1610634,1610658,1610664,1611021,1611041,1611270,1611275,1611277,1611313,1611332,1611584,1612560,1612825,1612993,1613018,1613041,1614265,1614272,1614344-1614345,1614384-1614385,1614397,1614405-1614406,1614574,1614591,1614593,1614596,1614604,1614689,1614807,1614835,1614891,1615417-1615418,1616182,1616236,1616463,1616719,1617417,1617451,1617463,1617711,1618158,1618613,1618624,1618709,1619222,1619411,1619695,1619800,1619808,1619815,1619823-1619824,1620512,1620581,1620585,1620634,1620898,1620905,1621115,1621123-1621124,1621168,1621192,1621201,1621706,1621962,1622197,1622201,1622207,1622250,1622479,1623364,1623766,1623827,1623949,1623969,1623973,1624216,1624317,1624551,1624559,1624973,1624993-1624994,1625025,1625036,1625158,1625224,1625237,1625299,1625348,1625620,1625916,1625962-1625963,1626021,1626053,1626163,1626168,1626175,1626191,1626265,1626770,1627047,1627052,1627228,1627346,1627470,1627473,1627479,1627503,1627586,1627590,1627715,1627731,1628180,1628198,1
628262,1628447,1628608,1629688,1629840,1629917,1630055-1630057,1630156,1630299,1630338,1630773,1631283-1631284,1631333-1631334,1631617-1631619,1631630,1631699,1631704,1631711,1631967-1631969,1631986,1631990,1631999,1632002-1632003,1632017,1632258,1632264,1632270,1632293,1632303,1632592,1632605,1633315,1633559-1633560,1633562,1633567,1633571,1633598,1633608,1633641,1633687,1633697,1633768,1633783,1634505,1634513,1634774,1634779,1634781,1634792,1634803,1634814,1634816,1634838,1634841,1634852,1634864,1634896,1634898,1635044-1635045,1635060,1635077,1635089,1635102,1635108,1635218,1635387,1635435,1635518,1635563,1635586,1636336,1636348,1636505,1636585,1636799,1637368,1637382,1637413,1637651,1637815,1638779-1638783,1639260,1639577,1639622,1639963,1639966,1639973,1640134,1640143,1640555-1640556,1640694-1640695,1640715,1640722-1640723,1640728,1640863-1640872,1641340,1641350,1641352,1641541,1641596-1641599,1641601,1641662,1641671,1641695,1641771,1641802,1641811,1641950,1642031,1642056,164211
9,1642285,1642648,1642667,1642954,1642959,1643111,1643178,1643186,1643204,1643287,1643767,1643774,1643982,1644016,1644106,1644366,1644383,1644397-1644398,1644407,1644479,1644547,1644552,1644554,1644588,1644645,1644650,1644654,1644689,1644750,1645421,1645424,1645459,1645585,1645611,1645637,1645646,1645660-1645663,1645888,1645901,1645948,1645966,1645970-1645971,1646014,1646164,1646174,1646684,1649743,1649803,1650015,1650239,1650529,1650797,1651323,1651382,1651643,1651652,1651730,1651988-1651989,1651996,1652024,1652035,1652058-1652059,1652075,1652127,1652158,1652467,1652965,1652971,1653207,1653446,1653463,1653484,1653572,1653579,1653591,1653804,1653809,1653848-1653850,1653882,1654116,1654743,1654756,1654778,1655049,1655054-1655055,1655086,1655237,1655248,1655996,1656027,1656394,1656400,1656425,1656427,1656453,1656628,1657804,1658470,1659483,1659527,1659550,1659578,1659765,1660154-1660155,1660383,1660409,1660426,1660676,1660870,1660872,1660897,1661069
/jackrabbit/trunk:1345480
Modified:
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java?rev=1661099&r1=1661098&r2=1661099&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java
(original)
+++
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/FieldNames.java
Fri Feb 20 11:51:59 2015
@@ -64,6 +64,12 @@ public final class FieldNames {
public static final String FULLTEXT_RELATIVE_NODE = "fullnode:";
/**
+ * Name of the field that contains those property names which are not found
+ * (or were null) for the given
+ */
+ public static final String NULL_PROPS = ":nullProps";
+
+ /**
* Used to select only the PATH field from the lucene documents
*/
public static final Set<String> PATH_SELECTOR = new HashSet<String>(
Modified:
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java?rev=1661099&r1=1661098&r2=1661099&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
(original)
+++
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
Fri Feb 20 11:51:59 2015
@@ -71,7 +71,6 @@ import static org.apache.jackrabbit.JcrC
import static org.apache.jackrabbit.JcrConstants.NT_BASE;
import static org.apache.jackrabbit.oak.api.Type.NAMES;
import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
-import static org.apache.jackrabbit.oak.commons.PathUtils.isAbsolute;
import static
org.apache.jackrabbit.oak.plugins.index.IndexConstants.DECLARING_NODE_TYPES;
import static
org.apache.jackrabbit.oak.plugins.index.IndexConstants.ENTRY_COUNT_PROPERTY_NAME;
import static
org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_COUNT;
@@ -507,6 +506,7 @@ class IndexDefinition implements Aggrega
private final String nodeTypeName;
private final Map<String, PropertyDefinition> propConfigs;
private final List<NamePattern> namePatterns;
+ private final List<PropertyDefinition> nullCheckEnabledProperties;
private final boolean indexesAllNodesOfMatchingType;
final float boost;
@@ -527,15 +527,18 @@ class IndexDefinition implements Aggrega
this.propertyTypes = getSupportedTypes(config,
INCLUDE_PROPERTY_TYPES, TYPES_ALLOW_ALL);
List<NamePattern> namePatterns = newArrayList();
+ List<PropertyDefinition> nonExistentProperties = newArrayList();
List<Aggregate.Include> propIncludes = newArrayList();
- this.propConfigs = collectPropConfigs(config, namePatterns,
propIncludes);
+ this.propConfigs = collectPropConfigs(config, namePatterns,
propIncludes, nonExistentProperties);
this.propAggregate = new Aggregate(nodeTypeName, propIncludes);
this.aggregate = combine(propAggregate, nodeTypeName);
this.namePatterns = ImmutableList.copyOf(namePatterns);
+ this.nullCheckEnabledProperties =
ImmutableList.copyOf(nonExistentProperties);
this.fulltextEnabled = aggregate.hasNodeAggregates() ||
hasAnyFullTextEnabledProperty();
this.propertyIndexEnabled = hasAnyPropertyIndexConfigured();
this.indexesAllNodesOfMatchingType =
allMatchingNodeByTypeIndexed();
+ validateRuleDefinition();
}
/**
@@ -555,6 +558,7 @@ class IndexDefinition implements Aggrega
this.propertyTypes = original.propertyTypes;
this.propertyIndexEnabled = original.propertyIndexEnabled;
this.propAggregate = original.propAggregate;
+ this.nullCheckEnabledProperties =
original.nullCheckEnabledProperties;
this.aggregate = combine(propAggregate, nodeTypeName);
this.fulltextEnabled = aggregate.hasNodeAggregates() ||
original.fulltextEnabled;
this.indexesAllNodesOfMatchingType =
allMatchingNodeByTypeIndexed();
@@ -582,6 +586,10 @@ class IndexDefinition implements Aggrega
return nodeTypeName;
}
+ public List<PropertyDefinition> getNullCheckEnabledProperties() {
+ return nullCheckEnabledProperties;
+ }
+
@Override
public String toString() {
String str = "IndexRule: "+ nodeTypeName;
@@ -674,7 +682,8 @@ class IndexDefinition implements Aggrega
}
private Map<String, PropertyDefinition> collectPropConfigs(NodeState
config, List<NamePattern> patterns,
-
List<Aggregate.Include> propAggregate) {
+
List<Aggregate.Include> propAggregate,
+
List<PropertyDefinition> nonExistentProperties) {
Map<String, PropertyDefinition> propDefns = newHashMap();
NodeState propNode =
config.getChildNode(LuceneIndexConstants.PROP_NODE);
@@ -700,9 +709,13 @@ class IndexDefinition implements Aggrega
propDefns.put(pd.name, pd);
}
- if (isRelativeProperty(pd.name)){
+ if (pd.relative){
propAggregate.add(new Aggregate.PropertyInclude(pd));
}
+
+ if (pd.nullCheckEnabled){
+ nonExistentProperties.add(pd);
+ }
}
}
return ImmutableMap.copyOf(propDefns);
@@ -745,6 +758,15 @@ class IndexDefinition implements Aggrega
return true;
}
+ //If there is nullCheckEnabled property which is not relative then
+ //all nodes would be indexed. relativeProperty with
nullCheckEnabled might
+ //not ensure that (OAK-1085)
+ for (PropertyDefinition pd : nullCheckEnabledProperties){
+ if (!pd.relative) {
+ return true;
+ }
+ }
+
//jcr:primaryType is present on all node. So if such a property
//is indexed then it would mean all nodes covered by this index
rule
//are indexed
@@ -764,6 +786,13 @@ class IndexDefinition implements Aggrega
}
return new Aggregate(nodeTypeName, includes);
}
+
+ private void validateRuleDefinition() {
+ if (!nullCheckEnabledProperties.isEmpty() && isBasedOnNtBase()){
+ throw new IllegalStateException("nt:base based rule cannot
have a " +
+ "PropertyDefinition with nullCheckEnabled");
+ }
+ }
}
/**
@@ -893,7 +922,7 @@ class IndexDefinition implements Aggrega
String propNodeName = propName;
//For proper propName use the propName as childNode name
- if(isRelativeProperty(propName)
+ if(PropertyDefinition.isRelativeProperty(propName)
|| propName.equals(includeAllProp)){
propNodeName = "prop" + i++;
}
@@ -955,7 +984,7 @@ class IndexDefinition implements Aggrega
private static NodeState getPropDefnNode(NodeState defn, String propName){
NodeState propNode = defn.getChildNode(LuceneIndexConstants.PROP_NODE);
NodeState propDefNode;
- if (isRelativeProperty(propName)) {
+ if (PropertyDefinition.isRelativeProperty(propName)) {
NodeState result = propNode;
for (String name : PathUtils.elements(propName)) {
result = result.getChildNode(name);
@@ -1175,7 +1204,4 @@ class IndexDefinition implements Aggrega
return defn.getChildNode(LuceneIndexConstants.INDEX_RULES).exists();
}
- private static boolean isRelativeProperty(String propertyName){
- return !isAbsolute(propertyName) &&
PathUtils.getNextSlash(propertyName, 0) > 0;
- }
}
Modified:
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java?rev=1661099&r1=1661098&r2=1661099&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
(original)
+++
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlanner.java
Fri Feb 20 11:51:59 2015
@@ -139,12 +139,11 @@ class IndexPlanner {
//for property index
if (indexingRule.propertyIndexEnabled) {
for (PropertyRestriction pr : filter.getPropertyRestrictions()) {
- if (pr.isNullRestriction()) {
- // ignore for planning
- continue;
- }
PropertyDefinition pd =
indexingRule.getConfig(pr.propertyName);
if (pd != null && pd.propertyIndexEnabled()) {
+ if (pr.isNullRestriction() && !pd.nullCheckEnabled){
+ continue;
+ }
indexedProps.add(pr.propertyName);
result.propDefns.put(pr.propertyName, pd);
}
Modified:
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java?rev=1661099&r1=1661098&r2=1661099&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java
(original)
+++
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexConstants.java
Fri Feb 20 11:51:59 2015
@@ -192,4 +192,10 @@ public interface LuceneIndexConstants {
* nt:file node under 'tika' node which refers to the config xml file
*/
String TIKA_CONFIG = "config.xml";
+
+ /**
+ * Property definition config indicating that null check support should be
+ * enabled for this property
+ */
+ String PROP_NULL_CHECK_ENABLED = "nullCheckEnabled";
}
Modified:
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java?rev=1661099&r1=1661098&r2=1661099&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
(original)
+++
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
Fri Feb 20 11:51:59 2015
@@ -298,6 +298,7 @@ public class LuceneIndexEditor implement
}
dirty |= indexAggregates(path, fields, state);
+ dirty |= indexNullCheckEnabledProps(path, fields, state);
if (isUpdate && !dirty) {
// updated the state but had no relevant changes
@@ -488,6 +489,46 @@ public class LuceneIndexEditor implement
return fields;
}
+ //~-------------------------------------------------------< NullCheck
Support >
+
+ private boolean indexNullCheckEnabledProps(String path, List<Field>
fields, NodeState state) {
+ boolean fieldAdded = false;
+ for (PropertyDefinition pd :
indexingRule.getNullCheckEnabledProperties()) {
+ if (isPropertyNull(state, pd)) {
+ fields.add(new StringField(FieldNames.NULL_PROPS, pd.name,
Field.Store.NO));
+ fieldAdded = true;
+ }
+ }
+ return fieldAdded;
+ }
+
+ /**
+ * Determine if the property as defined by PropertyDefinition exists or
not.
+ *
+ * <p>For relative property if the intermediate nodes do not exist then
property is
+ * <bold>not</bold> considered to be null</p>
+ *
+ * @return true if the property does not exist
+ */
+ private boolean isPropertyNull(NodeState state, PropertyDefinition pd){
+ NodeState propertyNode = getPropertyNode(state, pd);
+ if (!propertyNode.exists()){
+ return false;
+ }
+ return !propertyNode.hasProperty(pd.nonRelativeName);
+ }
+
+ private static NodeState getPropertyNode(NodeState nodeState,
PropertyDefinition pd) {
+ if (!pd.relative){
+ return nodeState;
+ }
+ NodeState node = nodeState;
+ for (String name : pd.ancestors) {
+ node = node.getChildNode(name);
+ }
+ return node;
+ }
+
//~-------------------------------------------------------< Aggregate >
@Override
Modified:
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java?rev=1661099&r1=1661098&r2=1661099&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
(original)
+++
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
Fri Feb 20 11:51:59 2015
@@ -657,6 +657,11 @@ public class LucenePropertyIndex impleme
private static Query createQuery(PropertyRestriction pr,
PropertyDefinition defn) {
int propType = determinePropertyType(defn, pr);
+
+ if (pr.isNullRestriction()){
+ return new TermQuery(new Term(FieldNames.NULL_PROPS, defn.name));
+ }
+
switch (propType) {
case PropertyType.DATE: {
Long first = pr.first != null ?
FieldFactory.dateToLong(pr.first.getValue(Type.DATE)) : null;
@@ -711,7 +716,7 @@ public class LucenePropertyIndex impleme
in.add(NumericRangeQuery.newDoubleRange(pr.propertyName, doubleVal, doubleVal,
true, true), BooleanClause.Occur.SHOULD);
}
return in;
- } else if (pr.first == null && pr.last == null ) {
+ } else if (pr.isNotNullRestriction()) {
// not null.
return NumericRangeQuery.newDoubleRange(pr.propertyName,
Double.MIN_VALUE, Double.MAX_VALUE, true, true);
}
@@ -740,7 +745,7 @@ public class LucenePropertyIndex impleme
in.add(NumericRangeQuery.newLongRange(pr.propertyName,
longVal, longVal, true, true), BooleanClause.Occur.SHOULD);
}
return in;
- } else if (pr.first == null && pr.last == null ) {
+ } else if (pr.isNotNullRestriction()) {
// not null.
return NumericRangeQuery.newLongRange(pr.propertyName,
Long.MIN_VALUE, Long.MAX_VALUE, true, true);
}
@@ -774,7 +779,7 @@ public class LucenePropertyIndex impleme
in.add(new TermQuery(new Term(pr.propertyName,
strVal)), BooleanClause.Occur.SHOULD);
}
return in;
- } else if (pr.first == null && pr.last == null ) {
+ } else if (pr.isNotNullRestriction()) {
return new TermRangeQuery(pr.propertyName, null, null,
true, true);
}
}
Modified:
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/PropertyDefinition.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/PropertyDefinition.java?rev=1661099&r1=1661098&r2=1661099&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/PropertyDefinition.java
(original)
+++
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/PropertyDefinition.java
Fri Feb 20 11:51:59 2015
@@ -19,16 +19,22 @@
package org.apache.jackrabbit.oak.plugins.index.lucene;
+import javax.annotation.CheckForNull;
import javax.jcr.PropertyType;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
import
org.apache.jackrabbit.oak.plugins.index.lucene.IndexDefinition.IndexingRule;
import org.apache.jackrabbit.oak.plugins.index.lucene.util.LuceneIndexHelper;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static com.google.common.collect.ImmutableList.copyOf;
+import static com.google.common.collect.Iterables.toArray;
+import static org.apache.jackrabbit.oak.commons.PathUtils.elements;
+import static org.apache.jackrabbit.oak.commons.PathUtils.isAbsolute;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.FIELD_BOOST;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PROP_IS_REGEX;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.util.ConfigUtil.getOptionalValue;
@@ -68,11 +74,25 @@ class PropertyDefinition {
final boolean ordered;
+ final boolean nullCheckEnabled;
+
final int includedPropertyTypes;
- public PropertyDefinition(IndexingRule idxDefn, String name, NodeState
defn) {
+ final boolean relative;
+
+ final String[] ancestors;
+
+ /**
+ * Property name excluding the relativePath. For regular expression based
definition
+ * its set to null
+ */
+ @CheckForNull
+ final String nonRelativeName;
+
+ public PropertyDefinition(IndexingRule idxDefn, String nodeName, NodeState
defn) {
this.isRegexp = getOptionalValue(defn, PROP_IS_REGEX, false);
- this.name = getName(defn, name);
+ this.name = getName(defn, nodeName);
+ this.relative = isRelativeProperty(name);
this.boost = getOptionalValue(defn, FIELD_BOOST, DEFAULT_BOOST);
//By default if a property is defined it is indexed
@@ -90,7 +110,11 @@ class PropertyDefinition {
//TODO Add test case for above cases
this.propertyType = getPropertyType(idxDefn, name, defn);
- }
+ this.nullCheckEnabled = getOptionalValue(defn,
LuceneIndexConstants.PROP_NULL_CHECK_ENABLED, false);
+ this.nonRelativeName = determineNonRelativeName();
+ this.ancestors = computeAncestors(name);
+ validate(); }
+
/**
* If 'analyzed' is enabled then property value would be used to evaluate
the
@@ -149,11 +173,40 @@ class PropertyDefinition {
", propertyIndex=" + propertyIndex +
", analyzed=" + analyzed +
", ordered=" + ordered +
+ ", nullCheckEnabled=" + nullCheckEnabled+
'}';
}
+ static boolean isRelativeProperty(String propertyName){
+ return !isAbsolute(propertyName) &&
PathUtils.getNextSlash(propertyName, 0) > 0;
+ }
+
//~---------------------------------------------< internal >
+ private void validate() {
+ if (nullCheckEnabled && isRegexp){
+ throw new IllegalStateException(String.format("%s can be set to
true for property definition using " +
+ "regular expression",
LuceneIndexConstants.PROP_NULL_CHECK_ENABLED));
+ }
+ }
+
+ private String determineNonRelativeName() {
+ if (isRegexp){
+ return null;
+ }
+
+ if (!relative){
+ return name;
+ }
+
+ return PathUtils.getName(name);
+ }
+
+ private static String[] computeAncestors(String parentPath) {
+ return toArray(copyOf(elements(PathUtils.getParentPath(parentPath))),
String.class);
+ }
+
+
private static String getName(NodeState definition, String defaultName){
PropertyState ps =
definition.getProperty(LuceneIndexConstants.PROP_NAME);
return ps == null ? defaultName : ps.getValue(Type.STRING);
Modified:
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinitionTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinitionTest.java?rev=1661099&r1=1661098&r2=1661099&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinitionTest.java
(original)
+++
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinitionTest.java
Fri Feb 20 11:51:59 2015
@@ -24,7 +24,6 @@ import javax.jcr.PropertyType;
import com.google.common.collect.ImmutableList;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.api.Tree;
-import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
import org.apache.jackrabbit.oak.plugins.tree.ImmutableTree;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
@@ -33,7 +32,6 @@ import org.apache.lucene.codecs.Codec;
import
org.apache.jackrabbit.oak.plugins.index.lucene.IndexDefinition.IndexingRule;
import org.junit.Test;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.ImmutableSet.of;
import static javax.jcr.PropertyType.TYPENAME_LONG;
import static javax.jcr.PropertyType.TYPENAME_STRING;
@@ -47,12 +45,14 @@ import static org.apache.jackrabbit.oak.
import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INDEX_RULES;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PROP_NAME;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PROP_NODE;
+import static
org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil.registerTestNodeType;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.util.LuceneIndexHelper.newLuceneIndexDefinition;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.util.LuceneIndexHelper.newLucenePropertyIndexDefinition;
import static
org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
import static
org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
import static
org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent.INITIAL_CONTENT;
import static
org.apache.jackrabbit.oak.plugins.tree.TreeConstants.OAK_CHILD_ORDER;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -150,13 +150,15 @@ public class IndexDefinitionTest {
assertNotNull(rule.getConfig("foo1/bar"));
assertEquals(PropertyType.DATE, rule.getConfig("foo1/bar").getType());
assertEquals(PropertyType.LONG,
rule.getConfig("foo2/bar2/baz").getType());
+ assertTrue(rule.getConfig("foo1/bar").relative);
+ assertArrayEquals(new String[]{"foo2", "bar2"},
rule.getConfig("foo2/bar2/baz").ancestors);
}
@Test
public void indexRuleSanity() throws Exception{
NodeBuilder rules = builder.child(INDEX_RULES);
rules.child("nt:folder").setProperty(LuceneIndexConstants.FIELD_BOOST,
2.0);
- child(rules, "nt:folder/properties/prop1")
+ TestUtil.child(rules, "nt:folder/properties/prop1")
.setProperty(LuceneIndexConstants.FIELD_BOOST, 3.0)
.setProperty(LuceneIndexConstants.PROP_TYPE,
PropertyType.TYPENAME_BOOLEAN);
@@ -239,9 +241,9 @@ public class IndexDefinitionTest {
public void indexRuleWithPropertyRegEx() throws Exception{
NodeBuilder rules = builder.child(INDEX_RULES);
rules.child("nt:folder");
- child(rules, "nt:folder/properties/prop1")
+ TestUtil.child(rules, "nt:folder/properties/prop1")
.setProperty(LuceneIndexConstants.FIELD_BOOST, 3.0);
- child(rules, "nt:folder/properties/prop2")
+ TestUtil.child(rules, "nt:folder/properties/prop2")
.setProperty(LuceneIndexConstants.PROP_NAME, "foo.*")
.setProperty(LuceneIndexConstants.PROP_IS_REGEX, true)
.setProperty(LuceneIndexConstants.FIELD_BOOST, 4.0);
@@ -263,10 +265,10 @@ public class IndexDefinitionTest {
public void indexRuleWithPropertyRegEx2() throws Exception{
NodeBuilder rules = builder.child(INDEX_RULES);
rules.child("nt:folder");
- child(rules, "nt:folder/properties/prop1")
+ TestUtil.child(rules, "nt:folder/properties/prop1")
.setProperty(LuceneIndexConstants.PROP_NAME, ".*")
.setProperty(LuceneIndexConstants.PROP_IS_REGEX, true);
- child(rules, "nt:folder/properties/prop2")
+ TestUtil.child(rules, "nt:folder/properties/prop2")
.setProperty(LuceneIndexConstants.PROP_NAME, "metadata/.*")
.setProperty(LuceneIndexConstants.PROP_IS_REGEX, true)
.setProperty(LuceneIndexConstants.FIELD_BOOST, 4.0);
@@ -289,11 +291,11 @@ public class IndexDefinitionTest {
public void indexRuleWithPropertyOrdering() throws Exception{
NodeBuilder rules = builder.child(INDEX_RULES);
rules.child("nt:folder");
- child(rules, "nt:folder/properties/prop1")
+ TestUtil.child(rules, "nt:folder/properties/prop1")
.setProperty(LuceneIndexConstants.PROP_NAME, "foo.*")
.setProperty(LuceneIndexConstants.PROP_IS_REGEX, true)
.setProperty(LuceneIndexConstants.FIELD_BOOST, 3.0);
- child(rules, "nt:folder/properties/prop2")
+ TestUtil.child(rules, "nt:folder/properties/prop2")
.setProperty(LuceneIndexConstants.PROP_NAME, ".*")
.setProperty(LuceneIndexConstants.PROP_IS_REGEX, true)
.setProperty(LuceneIndexConstants.FIELD_BOOST, 4.0);
@@ -324,7 +326,7 @@ public class IndexDefinitionTest {
public void skipTokenization() throws Exception{
NodeBuilder rules = builder.child(INDEX_RULES);
rules.child("nt:folder");
- child(rules, "nt:folder/properties/prop2")
+ TestUtil.child(rules, "nt:folder/properties/prop2")
.setProperty(LuceneIndexConstants.PROP_NAME, ".*")
.setProperty(LuceneIndexConstants.PROP_IS_REGEX, true)
.setProperty(LuceneIndexConstants.PROP_ANALYZED, true);
@@ -486,6 +488,37 @@ public class IndexDefinitionTest {
assertTrue(defn.hasCustomTikaConfig());
}
+ @Test(expected = IllegalStateException.class)
+ public void nullCheckEnabledWithNtBase() throws Exception{
+
builder.child(PROP_NODE).child("foo").setProperty(LuceneIndexConstants.PROP_NULL_CHECK_ENABLED,
true);
+ IndexDefinition idxDefn = new IndexDefinition(root,
builder.getNodeState());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void nullCheckEnabledWithRegex() throws Exception{
+ NodeBuilder rules = builder.child(INDEX_RULES);
+ rules.child(TestUtil.NT_TEST);
+ TestUtil.child(rules, "oak:TestNode/properties/prop2")
+ .setProperty(LuceneIndexConstants.PROP_NAME, ".*")
+ .setProperty(LuceneIndexConstants.PROP_IS_REGEX, true)
+ .setProperty(LuceneIndexConstants.PROP_NULL_CHECK_ENABLED,
true);
+ root = registerTestNodeType(builder).getNodeState();
+ IndexDefinition idxDefn = new IndexDefinition(root,
builder.getNodeState());
+ }
+
+ @Test
+ public void nullCheckEnabledWithTestNode() throws Exception{
+ NodeBuilder rules = builder.child(INDEX_RULES);
+ TestUtil.child(rules, "oak:TestNode/properties/prop2")
+ .setProperty(LuceneIndexConstants.PROP_NAME, "foo")
+ .setProperty(LuceneIndexConstants.PROP_NULL_CHECK_ENABLED,
true);
+ root = registerTestNodeType(builder).getNodeState();
+ IndexDefinition idxDefn = new IndexDefinition(root,
builder.getNodeState());
+
assertTrue(!idxDefn.getApplicableIndexingRule(TestUtil.NT_TEST).getNullCheckEnabledProperties().isEmpty());
+ }
+
+ //TODO indexesAllNodesOfMatchingType - with nullCheckEnabled
+
private static IndexingRule getRule(IndexDefinition defn, String typeName){
return defn.getApplicableIndexingRule(newTree(newNode(typeName)));
}
@@ -500,10 +533,4 @@ public class IndexDefinitionTest {
return builder;
}
- private static NodeBuilder child(NodeBuilder nb, String path) {
- for (String name : PathUtils.elements(checkNotNull(path))) {
- nb = nb.child(name);
- }
- return nb;
- }
}
Modified:
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java?rev=1661099&r1=1661098&r2=1661099&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java
(original)
+++
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java
Fri Feb 20 11:51:59 2015
@@ -55,8 +55,11 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.api.Type.STRINGS;
import static
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INDEX_DATA_CHILD_NAME;
+import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.INDEX_RULES;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.ORDERED_PROP_NAMES;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.VERSION;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil.NT_TEST;
+import static
org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil.registerTestNodeType;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.util.LuceneIndexHelper.newLuceneIndexDefinition;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.util.LuceneIndexHelper.newLucenePropertyIndexDefinition;
import static
org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
@@ -324,6 +327,42 @@ public class IndexPlannerTest {
assertEquals(numofDocs, plan.getEstimatedEntryCount());
}
+ @Test
+ public void nullPropertyCheck() throws Exception{
+ NodeBuilder defn = newLucenePropertyIndexDefinition(builder, "test",
of("foo"), "async");
+
+ IndexNode node = createIndexNode(new IndexDefinition(root,
defn.getNodeState()));
+ FilterImpl filter = createFilter("nt:base");
+ filter.restrictProperty("foo", Operator.EQUAL, null);
+ IndexPlanner planner = new IndexPlanner(node, "/foo", filter,
Collections.<OrderEntry>emptyList());
+ QueryIndex.IndexPlan plan = planner.getPlan();
+ assertNull("For null checks no plan should be returned",plan);
+ }
+
+ @Test
+ public void nullPropertyCheck2() throws Exception{
+ root = registerTestNodeType(builder).getNodeState();
+ NodeBuilder defn = newLucenePropertyIndexDefinition(builder, "test",
of("foo"), "async");
+ NodeBuilder rules = defn.child(INDEX_RULES);
+ TestUtil.child(rules, "oak:TestNode/properties/prop2")
+ .setProperty(LuceneIndexConstants.PROP_NAME, "foo")
+ .setProperty(LuceneIndexConstants.PROP_NULL_CHECK_ENABLED,
true)
+ .setProperty(LuceneIndexConstants.PROP_PROPERTY_INDEX, true);
+
+ IndexDefinition idxDefn = new IndexDefinition(root,
builder.getNodeState().getChildNode("test"));
+ IndexNode node = createIndexNode(idxDefn);
+
+ FilterImpl filter = createFilter(NT_TEST);
+ filter.restrictProperty("foo", Operator.EQUAL, null);
+
+ IndexPlanner planner = new IndexPlanner(node, "/foo", filter,
Collections.<OrderEntry>emptyList());
+ QueryIndex.IndexPlan plan = planner.getPlan();
+ assertNotNull("For null checks plan should be returned with
nullCheckEnabled", plan);
+ IndexPlanner.PlanResult pr =
+ (IndexPlanner.PlanResult)
plan.getAttribute(LucenePropertyIndex.ATTR_PLAN_RESULT);
+ assertNotNull(pr.getPropDefn(filter.getPropertyRestriction("foo")));
+ }
+
private IndexNode createIndexNode(IndexDefinition defn, long numOfDocs)
throws IOException {
return new IndexNode("foo", defn, createSampleDirectory(numOfDocs));
}
Modified:
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java?rev=1661099&r1=1661098&r2=1661099&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
(original)
+++
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
Fri Feb 20 11:51:59 2015
@@ -41,6 +41,8 @@ import static org.apache.jackrabbit.oak.
import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PERSISTENCE_FILE;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PERSISTENCE_NAME;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.PERSISTENCE_PATH;
+import static org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil.NT_TEST;
+import static
org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil.createNodeWithType;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.util.LuceneIndexHelper.newLucenePropertyIndexDefinition;
import static
org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_NODE_TYPES;
import static
org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent.INITIAL_CONTENT;
@@ -217,6 +219,81 @@ public class LuceneIndexTest {
}
@Test
+ public void testPropertyNonExistence() throws Exception {
+ root = TestUtil.registerTestNodeType(builder).getNodeState();
+
+ NodeBuilder index =
newLucenePropertyIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
+ "lucene", ImmutableSet.of("foo"), null);
+ NodeBuilder rules = index.child(INDEX_RULES);
+ NodeBuilder propNode =
rules.child(NT_TEST).child(LuceneIndexConstants.PROP_NODE);
+
+ NodeBuilder fooProp = propNode.child("foo");
+ fooProp.setProperty(LuceneIndexConstants.PROP_PROPERTY_INDEX, true);
+ fooProp.setProperty(LuceneIndexConstants.PROP_NULL_CHECK_ENABLED,
true);
+
+ NodeState before = builder.getNodeState();
+ createNodeWithType(builder, "a", NT_TEST).setProperty("foo", "bar");
+ createNodeWithType(builder, "b", NT_TEST).setProperty("foo", "bar");
+ createNodeWithType(builder, "c", NT_TEST);
+
+ NodeState after = builder.getNodeState();
+
+ NodeState indexed = HOOK.processCommit(before, after,CommitInfo.EMPTY);
+
+ IndexTracker tracker = new IndexTracker();
+ tracker.update(indexed);
+ AdvancedQueryIndex queryIndex = new LucenePropertyIndex(tracker);
+
+ FilterImpl filter = createFilter(NT_TEST);
+ filter.restrictProperty("foo", Operator.EQUAL, null);
+ assertFilter(filter, queryIndex, indexed, ImmutableList.of("/c"));
+ }
+
+ @Test
+ public void testRelativePropertyNonExistence() throws Exception {
+ root = TestUtil.registerTestNodeType(builder).getNodeState();
+
+ NodeBuilder index =
newLucenePropertyIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
+ "lucene", ImmutableSet.of("foo"), null);
+ NodeBuilder rules = index.child(INDEX_RULES);
+ NodeBuilder propNode =
rules.child(NT_TEST).child(LuceneIndexConstants.PROP_NODE);
+
+ propNode.child("bar")
+ .setProperty(LuceneIndexConstants.PROP_NAME, "jcr:content/bar")
+ .setProperty(LuceneIndexConstants.PROP_PROPERTY_INDEX, true)
+ .setProperty(LuceneIndexConstants.PROP_NULL_CHECK_ENABLED,
true);
+
+ NodeState before = builder.getNodeState();
+
+ NodeBuilder a1 = createNodeWithType(builder, "a1", NT_TEST);
+ a1.child("jcr:content").setProperty("bar", "foo");
+
+ NodeBuilder b1 = createNodeWithType(builder, "b1", NT_TEST);
+ b1.child("jcr:content");
+
+ NodeState after = builder.getNodeState();
+
+ NodeState indexed = HOOK.processCommit(before, after,CommitInfo.EMPTY);
+
+ IndexTracker tracker = new IndexTracker();
+ tracker.update(indexed);
+ AdvancedQueryIndex queryIndex = new LucenePropertyIndex(tracker);
+
+ FilterImpl filter = createFilter(NT_TEST);
+ filter.restrictProperty("jcr:content/bar", Operator.EQUAL, null);
+ assertFilter(filter, queryIndex, indexed, ImmutableList.of("/b1"));
+
+ builder.child("b1").child("jcr:content").setProperty("bar", "foo");
+ after = builder.getNodeState();
+ indexed = HOOK.processCommit(before, after, CommitInfo.EMPTY);
+ tracker.update(indexed);
+
+ filter = createFilter(NT_TEST);
+ filter.restrictProperty("jcr:content/bar", Operator.EQUAL, null);
+ assertFilter(filter, queryIndex, indexed,
Collections.<String>emptyList());
+ }
+
+ @Test
public void testPathRestrictions() throws Exception {
NodeBuilder idx =
newLucenePropertyIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME),
"lucene", ImmutableSet.of("foo"), null);
@@ -438,7 +515,8 @@ public class LuceneIndexTest {
for (String p : expected) {
assertTrue("Expected path " + p + " not found", paths.contains(p));
}
- assertEquals("Result set size is different", expected.size(),
paths.size());
+ assertEquals("Result set size is different \nExpected: " +
+ expected + "\nActual: " + paths, expected.size(),
paths.size());
return paths;
}
Modified:
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java?rev=1661099&r1=1661098&r2=1661099&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
(original)
+++
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
Fri Feb 20 11:51:59 2015
@@ -33,6 +33,7 @@ import com.google.common.collect.Immutab
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.oak.Oak;
import org.apache.jackrabbit.oak.api.CommitFailedException;
@@ -46,6 +47,7 @@ import org.apache.jackrabbit.oak.plugins
import
org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider;
import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
+import org.apache.jackrabbit.oak.plugins.nodetype.write.NodeTypeRegistry;
import org.apache.jackrabbit.oak.query.AbstractQueryTest;
import org.apache.jackrabbit.oak.spi.commit.Observer;
import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
@@ -279,8 +281,9 @@ public class LucenePropertyIndexTest ext
assertQuery(propabQuery, asList("/test/a", "/test/b", "/test"));
}
- private static void setNodeType(Tree t, String typeName){
+ private static Tree setNodeType(Tree t, String typeName){
t.setProperty(JcrConstants.JCR_PRIMARYTYPE, typeName, Type.NAME);
+ return t;
}
@Test
@@ -313,6 +316,35 @@ public class LucenePropertyIndexTest ext
}
@Test
+ public void propertyNonExistenceQuery() throws Exception {
+ NodeTypeRegistry.register(root,
IOUtils.toInputStream(TestUtil.TEST_NODE_TYPE), "test nodeType");
+
+ Tree idx = createIndex("test1", of("propa", "propb"));
+ Tree props = TestUtil.newRulePropTree(idx, TestUtil.NT_TEST);
+ Tree prop = props.addChild(TestUtil.unique("prop"));
+ prop.setProperty(LuceneIndexConstants.PROP_NAME, "propa");
+ prop.setProperty(LuceneIndexConstants.PROP_PROPERTY_INDEX, true);
+ prop.setProperty(LuceneIndexConstants.PROP_NULL_CHECK_ENABLED, true);
+ root.commit();
+
+ Tree test = root.getTree("/").addChild("test");
+ createNodeWithType(test, "a", "oak:TestNode").setProperty("propa",
"a");
+ createNodeWithType(test, "b", "oak:TestNode").setProperty("propa",
"c");
+ createNodeWithType(test, "c", "oak:TestNode").setProperty("propb",
"e");
+ root.commit();
+
+ String propabQuery = "select [jcr:path] from [oak:TestNode] where
[propa] is null";
+ assertThat(explain(propabQuery),
containsString("lucene:test1(/oak:index/test1) :nullProps:propa"));
+ assertQuery(propabQuery, asList("/test/c"));
+ }
+
+ private static Tree createNodeWithType(Tree t, String nodeName, String
typeName){
+ t = t.addChild(nodeName);
+ t.setProperty(JcrConstants.JCR_PRIMARYTYPE, typeName, Type.NAME);
+ return t;
+ }
+
+ @Test
public void rangeQueriesWithLong() throws Exception {
Tree idx = createIndex("test1", of("propa", "propb"));
Tree propIdx = idx.addChild(PROP_NODE).addChild("propa");
Modified:
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/TestUtil.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/TestUtil.java?rev=1661099&r1=1661098&r2=1661099&view=diff
==============================================================================
---
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/TestUtil.java
(original)
+++
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/TestUtil.java
Fri Feb 20 11:51:59 2015
@@ -26,13 +26,38 @@ import java.util.concurrent.atomic.Atomi
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.apache.commons.io.IOUtils;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.core.SystemRoot;
import org.apache.jackrabbit.oak.plugins.index.lucene.util.LuceneIndexHelper;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
+import org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState;
+import org.apache.jackrabbit.oak.plugins.name.NamespaceEditorProvider;
+import org.apache.jackrabbit.oak.plugins.nodetype.TypeEditorProvider;
+import org.apache.jackrabbit.oak.plugins.nodetype.write.NodeTypeRegistry;
+import org.apache.jackrabbit.oak.spi.commit.CompositeEditorProvider;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.state.ApplyDiff;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+
+import static com.google.common.base.Preconditions.checkNotNull;
public class TestUtil {
private static final AtomicInteger COUNTER = new AtomicInteger();
+ public static final String NT_TEST = "oak:TestNode";
+
+ public static final String TEST_NODE_TYPE = "[oak:TestNode]\n" +
+ " - * (UNDEFINED) multiple\n" +
+ " - * (UNDEFINED)\n" +
+ " + * (nt:base) = oak:TestNode VERSION";
+
static void useV2(NodeBuilder idxNb) {
idxNb.setProperty(LuceneIndexConstants.COMPAT_MODE,
IndexFormatVersion.V2.getVersion());
}
@@ -87,6 +112,13 @@ public class TestUtil {
return props;
}
+ public static NodeBuilder child(NodeBuilder nb, String path) {
+ for (String name : PathUtils.elements(checkNotNull(path))) {
+ nb = nb.child(name);
+ }
+ return nb;
+ }
+
static class AggregatorBuilder {
private final Tree aggs;
@@ -107,4 +139,34 @@ public class TestUtil {
static String unique(String name){
return name + COUNTER.getAndIncrement();
}
+
+ public static NodeBuilder registerTestNodeType(NodeBuilder builder){
+ registerNodeType(builder, TEST_NODE_TYPE);
+ return builder;
+ }
+
+ public static void registerNodeType(NodeBuilder builder, String
nodeTypeDefn){
+ //Taken from
org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent
+ NodeState base = ModifiedNodeState.squeeze(builder.getNodeState());
+ NodeStore store = new MemoryNodeStore(base);
+ Root root = new SystemRoot(
+ store, new EditorHook(new CompositeEditorProvider(
+ new NamespaceEditorProvider(),
+ new TypeEditorProvider())));
+ NodeTypeRegistry.register(root, IOUtils.toInputStream(nodeTypeDefn),
"test node types");
+ NodeState target = store.getRoot();
+ target.compareAgainstBaseState(base, new ApplyDiff(builder));
+ }
+
+ public static Tree createNodeWithType(Tree t, String nodeName, String
typeName){
+ t = t.addChild(nodeName);
+ t.setProperty(JcrConstants.JCR_PRIMARYTYPE, typeName, Type.NAME);
+ return t;
+ }
+
+ public static NodeBuilder createNodeWithType(NodeBuilder builder, String
nodeName, String typeName){
+ builder = builder.child(nodeName);
+ builder.setProperty(JcrConstants.JCR_PRIMARYTYPE, typeName, Type.NAME);
+ return builder;
+ }
}