You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2016/04/05 18:35:54 UTC

[1/3] incubator-ranger git commit: RANGER-908: Ranger policy model updated to support row-filtering

Repository: incubator-ranger
Updated Branches:
  refs/heads/master 38b79e725 -> 2c7f617be


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java
index a0047a5..b349768 100644
--- a/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java
+++ b/security-admin/src/main/java/org/apache/ranger/service/RangerServiceDefServiceBase.java
@@ -44,6 +44,7 @@ import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumElementDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerRowFilterDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef;
 import org.apache.ranger.plugin.util.SearchFilter;
 import org.apache.ranger.plugin.util.ServiceDefUtil;
@@ -144,7 +145,9 @@ public abstract class RangerServiceDefServiceBase<T extends XXServiceDefBase, V
 			serviceDef.setEnums(enums);
 		}
 
-		RangerDataMaskDef dataMaskDef = new RangerDataMaskDef();
+		RangerDataMaskDef  dataMaskDef  = new RangerDataMaskDef();
+		RangerRowFilterDef rowFilterDef = new RangerRowFilterDef();
+
 		List<XXDataMaskTypeDef> xDataMaskTypes = daoMgr.getXXDataMaskTypeDef().findByServiceDefId(serviceDefId);
 		if (!stringUtil.isEmpty(xDataMaskTypes)) {
 			List<RangerDataMaskTypeDef> dataMaskTypes = new ArrayList<RangerDataMaskTypeDef>();
@@ -163,6 +166,12 @@ public abstract class RangerServiceDefServiceBase<T extends XXServiceDefBase, V
 
 					dataMaskDef.getResources().add(dataMaskResource);
 				}
+
+				if (StringUtils.isNotEmpty(xResource.getRowFilterOptions())) {
+					RangerResourceDef resource = jsonToObject(xResource.getRowFilterOptions(), RangerResourceDef.class);
+
+					rowFilterDef.getResources().add(resource);
+				}
 			}
 		}
 
@@ -173,9 +182,16 @@ public abstract class RangerServiceDefServiceBase<T extends XXServiceDefBase, V
 
 					dataMaskDef.getAccessTypes().add(dataMaskAccessType);
 				}
+
+				if(StringUtils.isNotEmpty(xAtd.getRowFilterOptions())) {
+					RangerAccessTypeDef accessType = jsonToObject(xAtd.getRowFilterOptions(), RangerAccessTypeDef.class);
+
+					rowFilterDef.getAccessTypes().add(accessType);
+				}
 			}
 		}
 		serviceDef.setDataMaskDef(dataMaskDef);
+		serviceDef.setRowFilterDef(rowFilterDef);
 
 		ServiceDefUtil.normalize(serviceDef);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
----------------------------------------------------------------------
diff --git a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
index 739b5ca..c70dcba 100644
--- a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
+++ b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
@@ -593,6 +593,27 @@
 		<query>select obj from XXPolicyItemDataMaskInfo obj where obj.type = :type</query>
 	</named-query>
 
+	<!-- XXPolicyItemRowFilterInfo -->
+	<named-query name="XXPolicyItemRowFilterInfo.findByPolicyItemId">
+		<query>select obj from XXPolicyItemRowFilterInfo obj where obj.policyItemId = :polItemId</query>
+	</named-query>
+
+	<named-query name="XXPolicyItemRowFilterInfo.findByPolicyId">
+		<query>select obj from XXPolicyItemRowFilterInfo obj, XXPolicyItem item
+			where obj.policyItemId = item.id
+			and item.policyId = :policyId
+			order by obj.policyItemId
+		</query>
+	</named-query>
+
+	<named-query name="XXPolicyItemRowFilterInfo.findByServiceId">
+		<query>select obj from XXPolicyItemRowFilterInfo obj, XXPolicyItem item
+			where obj.policyItemId = item.id
+			and item.policyId in (select policy.id from XXPolicy policy where policy.service = :serviceId)
+			order by item.policyId, obj.policyItemId
+		</query>
+	</named-query>
+
 	<!-- XXDataHist -->
 	<named-query name="XXDataHist.findLatestByObjectClassTypeAndObjectId">
 		<query>select obj from XXDataHist obj where obj.objectId = :objectId 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
----------------------------------------------------------------------
diff --git a/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
index 5cb0290..17da9be 100644
--- a/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
+++ b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
@@ -312,6 +312,10 @@ public class TestServiceDBStore {
 		XXEnumElementDef xEnumElementDef = Mockito.mock(XXEnumElementDef.class);
 		XXAccessTypeDefGrants xAccessTypeDefGrants = Mockito
 				.mock(XXAccessTypeDefGrants.class);
+		List<XXAccessTypeDef> xAccessTypeDefs = new ArrayList<XXAccessTypeDef>();
+		xAccessTypeDefs.add(xAccessTypeDef);
+		List<XXResourceDef> xResourceDefs = new ArrayList<XXResourceDef>();
+		xResourceDefs.add(xResourceDef);
 
 		RangerServiceConfigDef rangerServiceConfigDef = Mockito
 				.mock(RangerServiceConfigDef.class);
@@ -353,6 +357,7 @@ public class TestServiceDBStore {
 				.thenReturn(xResourceDef);
 		Mockito.when(xResourceDefDao.create(xResourceDef)).thenReturn(
 				xResourceDef);
+		Mockito.when(xResourceDefDao.findByServiceDefId(xServiceDef.getId())).thenReturn(xResourceDefs);
 
 		Mockito.when(daoManager.getXXAccessTypeDef()).thenReturn(
 				xAccessTypeDefDao);
@@ -362,6 +367,7 @@ public class TestServiceDBStore {
 				.thenReturn(xAccessTypeDef);
 		Mockito.when(xAccessTypeDefDao.create(xAccessTypeDef)).thenReturn(
 				xAccessTypeDef);
+		Mockito.when(xAccessTypeDefDao.findByServiceDefId(xServiceDef.getId())).thenReturn(xAccessTypeDefs);
 
 		Mockito.when(daoManager.getXXAccessTypeDefGrants()).thenReturn(
 				xAccessTypeDefGrantsDao);
@@ -1305,6 +1311,7 @@ public class TestServiceDBStore {
 		XXService xService = Mockito.mock(XXService.class);
 		XXPolicyItemDao xPolicyItemDao = Mockito.mock(XXPolicyItemDao.class);
 		XXPolicyItemDataMaskInfoDao xxPolicyItemDataMaskInfoDao = Mockito.mock(XXPolicyItemDataMaskInfoDao.class);
+		XXPolicyItemRowFilterInfoDao xxPolicyItemRowFilterInfoDao = Mockito.mock(XXPolicyItemRowFilterInfoDao.class);
 		XXPolicyItemConditionDao xPolicyItemConditionDao = Mockito
 				.mock(XXPolicyItemConditionDao.class);
 		XXPolicyItemGroupPermDao xPolicyItemGroupPermDao = Mockito
@@ -1367,6 +1374,7 @@ public class TestServiceDBStore {
 		policyItemList.add(policyItem);
 
 		List<XXPolicyItemDataMaskInfo> policyItemDataMaskInfoList = new ArrayList<XXPolicyItemDataMaskInfo>();
+		List<XXPolicyItemRowFilterInfo> policyItemRowFilterInfoList = new ArrayList<XXPolicyItemRowFilterInfo>();
 
 		List<XXPolicyItemCondition> policyItemConditionList = new ArrayList<XXPolicyItemCondition>();
 		XXPolicyItemCondition policyItemCondition = new XXPolicyItemCondition();
@@ -1478,6 +1486,9 @@ public class TestServiceDBStore {
 		Mockito.when(daoManager.getXXPolicyItemDataMaskInfo()).thenReturn(xxPolicyItemDataMaskInfoDao);
 		Mockito.when(xxPolicyItemDataMaskInfoDao.findByPolicyItemId(policyItem.getId())).thenReturn(policyItemDataMaskInfoList);
 
+		Mockito.when(daoManager.getXXPolicyItemRowFilterInfo()).thenReturn(xxPolicyItemRowFilterInfoDao);
+		Mockito.when(xxPolicyItemRowFilterInfoDao.findByPolicyItemId(policyItem.getId())).thenReturn(policyItemRowFilterInfoList);
+
 		Mockito.when(daoManager.getXXPolicyItemCondition()).thenReturn(
 				xPolicyItemConditionDao);
 		Mockito.when(
@@ -2143,6 +2154,7 @@ public class TestServiceDBStore {
 		XXService xService = Mockito.mock(XXService.class);
 		XXPolicyItemDao xPolicyItemDao = Mockito.mock(XXPolicyItemDao.class);
 		XXPolicyItemDataMaskInfoDao xPolicyItemDataMaskInfoDao = Mockito.mock(XXPolicyItemDataMaskInfoDao.class);
+		XXPolicyItemRowFilterInfoDao xPolicyItemRowFilterInfoDao = Mockito.mock(XXPolicyItemRowFilterInfoDao.class);
 		XXPolicyItemConditionDao xPolicyItemConditionDao = Mockito
 				.mock(XXPolicyItemConditionDao.class);
 		XXPolicyItemGroupPermDao xPolicyItemGroupPermDao = Mockito
@@ -2179,6 +2191,7 @@ public class TestServiceDBStore {
 		policyItemList.add(policyItem);
 
 		List<XXPolicyItemDataMaskInfo> policyItemDataMaskInfo = new ArrayList<XXPolicyItemDataMaskInfo>();
+		List<XXPolicyItemRowFilterInfo> policyItemRowFilterInfo = new ArrayList<XXPolicyItemRowFilterInfo>();
 
 		List<XXPolicyItemCondition> policyItemConditionList = new ArrayList<XXPolicyItemCondition>();
 		XXPolicyItemCondition policyItemCondition = new XXPolicyItemCondition();
@@ -2284,6 +2297,10 @@ public class TestServiceDBStore {
 		Mockito.when(xPolicyItemDataMaskInfoDao.findByPolicyId(policyItem.getId()))
 				.thenReturn(policyItemDataMaskInfo);
 
+		Mockito.when(daoManager.getXXPolicyItemRowFilterInfo()).thenReturn(xPolicyItemRowFilterInfoDao);
+		Mockito.when(xPolicyItemRowFilterInfoDao.findByPolicyId(policyItem.getId()))
+				.thenReturn(policyItemRowFilterInfo);
+
 		Mockito.when(daoManager.getXXPolicyItemCondition()).thenReturn(
 				xPolicyItemConditionDao);
 		Mockito.when(


[3/3] incubator-ranger git commit: RANGER-908: Ranger policy model updated to support row-filtering

Posted by ma...@apache.org.
RANGER-908: Ranger policy model updated to support row-filtering


Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/2c7f617b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/2c7f617b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/2c7f617b

Branch: refs/heads/master
Commit: 2c7f617be49fb9fc93b1e0e4fab62701602f6c55
Parents: 38b79e7
Author: Madhan Neethiraj <ma...@apache.org>
Authored: Sun Apr 3 22:01:17 2016 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Tue Apr 5 09:20:12 2016 -0700

----------------------------------------------------------------------
 .../ranger/plugin/model/RangerPolicy.java       | 219 ++++++++-
 .../ranger/plugin/model/RangerServiceDef.java   | 164 ++++++-
 .../validation/RangerServiceDefHelper.java      |   6 +
 .../plugin/policyengine/RangerPolicyEngine.java |   2 +
 .../policyengine/RangerPolicyEngineImpl.java    |  37 +-
 .../policyengine/RangerPolicyRepository.java    |  26 +-
 .../policyengine/RangerRowFilterResult.java     |  80 ++++
 .../RangerDataMaskPolicyItemEvaluator.java      |  10 +-
 ...angerDefaultDataMaskPolicyItemEvaluator.java |  28 +-
 .../RangerDefaultPolicyEvaluator.java           | 468 ++++++++++++-------
 ...ngerDefaultRowFilterPolicyItemEvaluator.java |  42 ++
 .../policyevaluator/RangerPolicyEvaluator.java  |   3 +
 .../RangerPolicyItemEvaluator.java              |   3 +-
 .../RangerRowFilterPolicyItemEvaluator.java     |  28 ++
 .../ranger/plugin/service/RangerBasePlugin.java |  12 +
 .../plugin/store/AbstractPredicateUtil.java     |   8 +-
 .../ranger/plugin/util/ServiceDefUtil.java      |  48 ++
 .../service-defs/ranger-servicedef-hive.json    |  30 +-
 .../plugin/policyengine/TestPolicyEngine.java   |  14 +-
 .../test_policyengine_hive_mask_filter.json     | 243 ++++++++++
 .../test_policyengine_hive_masking.json         | 156 -------
 .../hive/authorizer/RangerHiveAuditHandler.java |  18 +-
 .../db/mysql/patches/020-datamask-policy.sql    |  23 +
 .../db/postgres/patches/020-datamask-policy.sql |  30 ++
 .../ranger/biz/RangerPolicyRetriever.java       |  68 ++-
 .../org/apache/ranger/biz/ServiceDBStore.java   | 312 ++++++++-----
 .../java/org/apache/ranger/biz/XUserMgr.java    |  26 +-
 .../org/apache/ranger/common/AppConstants.java  |   6 +-
 .../apache/ranger/db/RangerDaoManagerBase.java  |  10 +
 .../ranger/db/XXPolicyItemRowFilterInfoDao.java |  71 +++
 .../apache/ranger/entity/XXAccessTypeDef.java   |  23 +-
 .../ranger/entity/XXPolicyItemDataMaskInfo.java |  41 +-
 .../entity/XXPolicyItemRowFilterInfo.java       | 176 +++++++
 .../org/apache/ranger/entity/XXResourceDef.java |  21 +
 .../service/RangerServiceDefServiceBase.java    |  18 +-
 .../resources/META-INF/jpa_named_queries.xml    |  21 +
 .../apache/ranger/biz/TestServiceDBStore.java   |  17 +
 37 files changed, 1952 insertions(+), 556 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
index f022707..d8e19b7 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
@@ -40,10 +40,15 @@ import org.codehaus.jackson.map.annotate.JsonSerialize;
 @XmlRootElement
 @XmlAccessorType(XmlAccessType.FIELD)
 public class RangerPolicy extends RangerBaseModelObject implements java.io.Serializable {
-	public static final int POLICY_TYPE_ACCESS   = 0;
-	public static final int POLICY_TYPE_DATAMASK = 1;
+	public static final int POLICY_TYPE_ACCESS    = 0;
+	public static final int POLICY_TYPE_DATAMASK  = 1;
+	public static final int POLICY_TYPE_ROWFILTER = 2;
 
-	public static final int[] POLICY_TYPES = new int[] { POLICY_TYPE_ACCESS, POLICY_TYPE_DATAMASK };
+	public static final int[] POLICY_TYPES = new int[] {
+			POLICY_TYPE_ACCESS,
+			POLICY_TYPE_DATAMASK,
+			POLICY_TYPE_ROWFILTER
+	};
 
 	// For future use
 	private static final long serialVersionUID = 1L;
@@ -59,7 +64,8 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 	private List<RangerPolicyItem>            denyPolicyItems	= null;
 	private List<RangerPolicyItem>            allowExceptions	= null;
 	private List<RangerPolicyItem>            denyExceptions	= null;
-	private List<RangerDataMaskPolicyItem>    dataMaskPolicyItems = null;
+	private List<RangerDataMaskPolicyItem>    dataMaskPolicyItems  = null;
+	private List<RangerRowFilterPolicyItem>   rowFilterPolicyItems = null;
 
 
 	/**
@@ -93,6 +99,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		setAllowExceptions(null);
 		setDenyExceptions(null);
 		setDataMaskPolicyItems(null);
+		setRowFilterPolicyItems(null);
 	}
 
 	/**
@@ -113,7 +120,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		setAllowExceptions(other.getAllowExceptions());
 		setDenyExceptions(other.getDenyExceptions());
 		setDataMaskPolicyItems(other.getDataMaskPolicyItems());
-
+		setRowFilterPolicyItems(other.getRowFilterPolicyItems());
 	}
 
 	/**
@@ -362,6 +369,28 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		}
 	}
 
+	public List<RangerRowFilterPolicyItem> getRowFilterPolicyItems() {
+		return rowFilterPolicyItems;
+	}
+
+	public void setRowFilterPolicyItems(List<RangerRowFilterPolicyItem> rowFilterPolicyItems) {
+		if(this.rowFilterPolicyItems == null) {
+			this.rowFilterPolicyItems = new ArrayList<RangerRowFilterPolicyItem>();
+		}
+
+		if(this.rowFilterPolicyItems == rowFilterPolicyItems) {
+			return;
+		}
+
+		this.rowFilterPolicyItems.clear();
+
+		if(rowFilterPolicyItems != null) {
+			for(RangerRowFilterPolicyItem rowFilterPolicyItem : rowFilterPolicyItems) {
+				this.rowFilterPolicyItems.add(rowFilterPolicyItem);
+			}
+		}
+	}
+
 	@Override
 	public String toString( ) {
 		StringBuilder sb = new StringBuilder();
@@ -433,6 +462,26 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		}
 		sb.append("} ");
 
+		sb.append("dataMaskPolicyItems={");
+		if(dataMaskPolicyItems != null) {
+			for(RangerDataMaskPolicyItem dataMaskPolicyItem : dataMaskPolicyItems) {
+				if(dataMaskPolicyItem != null) {
+					dataMaskPolicyItem.toString(sb);
+				}
+			}
+		}
+		sb.append("} ");
+
+		sb.append("rowFilterPolicyItems={");
+		if(rowFilterPolicyItems != null) {
+			for(RangerRowFilterPolicyItem rowFilterPolicyItem : rowFilterPolicyItems) {
+				if(rowFilterPolicyItem != null) {
+					rowFilterPolicyItem.toString(sb);
+				}
+			}
+		}
+		sb.append("} ");
+
 		sb.append("}");
 
 		return sb;
@@ -899,7 +948,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 		 * @param dataMaskInfo the dataMaskInfo to set
 		 */
 		public void setDataMaskInfo(RangerPolicyItemDataMaskInfo dataMaskInfo) {
-			this.dataMaskInfo = dataMaskInfo;
+			this.dataMaskInfo = dataMaskInfo == null ? new RangerPolicyItemDataMaskInfo() : dataMaskInfo;
 		}
 
 		@Override
@@ -960,6 +1009,93 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 	@JsonIgnoreProperties(ignoreUnknown=true)
 	@XmlRootElement
 	@XmlAccessorType(XmlAccessType.FIELD)
+	public static class RangerRowFilterPolicyItem extends RangerPolicyItem implements java.io.Serializable {
+		private static final long serialVersionUID = 1L;
+
+		private RangerPolicyItemRowFilterInfo rowFilterInfo = null;
+
+		public RangerRowFilterPolicyItem() {
+			this(null, null, null, null, null, null);
+		}
+
+		public RangerRowFilterPolicyItem(RangerPolicyItemRowFilterInfo rowFilterInfo, List<RangerPolicyItemAccess> accesses, List<String> users, List<String> groups, List<RangerPolicyItemCondition> conditions, Boolean delegateAdmin) {
+			super(accesses, users, groups, conditions, delegateAdmin);
+
+			setRowFilterInfo(rowFilterInfo);
+		}
+
+		/**
+		 * @return the rowFilterInfo
+		 */
+		public RangerPolicyItemRowFilterInfo getRowFilterInfo() {
+			return rowFilterInfo;
+		}
+
+		/**
+		 * @param rowFilterInfo the rowFilterInfo to set
+		 */
+		public void setRowFilterInfo(RangerPolicyItemRowFilterInfo rowFilterInfo) {
+			this.rowFilterInfo = rowFilterInfo == null ? new RangerPolicyItemRowFilterInfo() : rowFilterInfo;
+		}
+
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = super.hashCode();
+			result = prime * result + ((rowFilterInfo == null) ? 0 : rowFilterInfo.hashCode());
+			return result;
+		}
+
+		@Override
+		public boolean equals(Object obj) {
+			if(! super.equals(obj))
+				return false;
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			RangerRowFilterPolicyItem other = (RangerRowFilterPolicyItem) obj;
+			if (rowFilterInfo == null) {
+				if (other.rowFilterInfo != null)
+					return false;
+			} else if (!rowFilterInfo.equals(other.rowFilterInfo))
+				return false;
+			return true;
+		}
+
+		@Override
+		public String toString( ) {
+			StringBuilder sb = new StringBuilder();
+
+			toString(sb);
+
+			return sb.toString();
+		}
+
+		public StringBuilder toString(StringBuilder sb) {
+			sb.append("RangerRowFilterPolicyItem={");
+
+			super.toString(sb);
+
+			sb.append("rowFilterInfo={");
+			if(rowFilterInfo != null) {
+				rowFilterInfo.toString(sb);
+			}
+			sb.append("} ");
+
+			sb.append("}");
+
+			return sb;
+		}
+	}
+
+	@JsonAutoDetect(fieldVisibility=Visibility.ANY)
+	@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+	@JsonIgnoreProperties(ignoreUnknown=true)
+	@XmlRootElement
+	@XmlAccessorType(XmlAccessType.FIELD)
 	public static class RangerPolicyItemAccess implements java.io.Serializable {
 		private static final long serialVersionUID = 1L;
 
@@ -1283,4 +1419,75 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
 			return sb;
 		}
 	}
+
+	@JsonAutoDetect(fieldVisibility=Visibility.ANY)
+	@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+	@JsonIgnoreProperties(ignoreUnknown=true)
+	@XmlRootElement
+	@XmlAccessorType(XmlAccessType.FIELD)
+	public static class RangerPolicyItemRowFilterInfo implements java.io.Serializable {
+		private static final long serialVersionUID = 1L;
+
+		private String filterExpr = null;
+
+		public RangerPolicyItemRowFilterInfo() { }
+
+		public RangerPolicyItemRowFilterInfo(String filterExpr) {
+			setFilterExpr(filterExpr);
+		}
+
+		public String getFilterExpr() {
+			return filterExpr;
+		}
+
+		public void setFilterExpr(String filterExpr) {
+			this.filterExpr = filterExpr;
+		}
+
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = super.hashCode();
+			result = prime * result + ((filterExpr == null) ? 0 : filterExpr.hashCode());
+			return result;
+		}
+
+		@Override
+		public boolean equals(Object obj) {
+			if(! super.equals(obj))
+				return false;
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			RangerPolicyItemRowFilterInfo other = (RangerPolicyItemRowFilterInfo) obj;
+			if (filterExpr == null) {
+				if (other.filterExpr != null)
+					return false;
+			} else if (!filterExpr.equals(other.filterExpr))
+				return false;
+			return true;
+		}
+
+		@Override
+		public String toString( ) {
+			StringBuilder sb = new StringBuilder();
+
+			toString(sb);
+
+			return sb.toString();
+		}
+
+		public StringBuilder toString(StringBuilder sb) {
+			sb.append("RangerPolicyItemDataMaskInfo={");
+
+			sb.append("filterExpr={").append(filterExpr).append("} ");
+
+			sb.append("}");
+
+			return sb;
+		}
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
index 1dac6e8..0f0e5ee 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
@@ -59,14 +59,15 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 	private List<RangerContextEnricherDef> contextEnrichers = null;
 	private List<RangerEnumDef>            enums            = null;
 	private RangerDataMaskDef              dataMaskDef      = null;
+	private RangerRowFilterDef             rowFilterDef     = null;
 
 
 	public RangerServiceDef() {
-		this(null, null, null, null, null, null, null, null, null, null, null, null);
+		this(null, null, null, null, null, null, null, null, null, null, null, null, null);
 	}
 
 	public RangerServiceDef(String name, String implClass, String label, String description, Map<String, String> options, List<RangerServiceConfigDef> configs, List<RangerResourceDef> resources, List<RangerAccessTypeDef> accessTypes, List<RangerPolicyConditionDef> policyConditions, List<RangerContextEnricherDef> contextEnrichers, List<RangerEnumDef> enums) {
-		this(name, implClass, label, description, options, configs, resources, accessTypes, policyConditions, contextEnrichers, enums, null);
+		this(name, implClass, label, description, options, configs, resources, accessTypes, policyConditions, contextEnrichers, enums, null, null);
 	}
 
 	/**
@@ -83,7 +84,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 	 * @param dataMaskDef
 	 * @param enums
 	 */
-	public RangerServiceDef(String name, String implClass, String label, String description, Map<String, String> options, List<RangerServiceConfigDef> configs, List<RangerResourceDef> resources, List<RangerAccessTypeDef> accessTypes, List<RangerPolicyConditionDef> policyConditions, List<RangerContextEnricherDef> contextEnrichers, List<RangerEnumDef> enums, RangerDataMaskDef dataMaskDef) {
+	public RangerServiceDef(String name, String implClass, String label, String description, Map<String, String> options, List<RangerServiceConfigDef> configs, List<RangerResourceDef> resources, List<RangerAccessTypeDef> accessTypes, List<RangerPolicyConditionDef> policyConditions, List<RangerContextEnricherDef> contextEnrichers, List<RangerEnumDef> enums, RangerDataMaskDef dataMaskDef, RangerRowFilterDef rowFilterDef) {
 		super();
 
 		setName(name);
@@ -98,6 +99,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 		setContextEnrichers(contextEnrichers);
 		setEnums(enums);
 		setDataMaskDef(dataMaskDef);
+		setRowFilterDef(rowFilterDef);
 	}
 
 	/**
@@ -116,6 +118,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 		setPolicyConditions(other.getPolicyConditions());
 		setEnums(other.getEnums());
 		setDataMaskDef(other.getDataMaskDef());
+		setRowFilterDef(other.getRowFilterDef());
 	}
 
 	/**
@@ -404,6 +407,14 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 		this.dataMaskDef = dataMaskDef == null ? new RangerDataMaskDef() : dataMaskDef;
 	}
 
+	public RangerRowFilterDef getRowFilterDef() {
+		return rowFilterDef;
+	}
+
+	public void setRowFilterDef(RangerRowFilterDef rowFilterDef) {
+		this.rowFilterDef = rowFilterDef == null ? new RangerRowFilterDef() : rowFilterDef;
+	}
+
 	@Override
 	public String toString( ) {
 		StringBuilder sb = new StringBuilder();
@@ -499,6 +510,12 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 		}
 		sb.append("} ");
 
+		sb.append("rowFilterDef={");
+		if(rowFilterDef != null) {
+			rowFilterDef.toString(sb);
+		}
+		sb.append("} ");
+
 		sb.append("}");
 
 		return sb;
@@ -2880,4 +2897,145 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 			return true;
 		}
 	}
+
+	@JsonAutoDetect(fieldVisibility=Visibility.ANY)
+	@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+	@JsonIgnoreProperties(ignoreUnknown=true)
+	@XmlRootElement
+	@XmlAccessorType(XmlAccessType.FIELD)
+	public static class RangerRowFilterDef implements java.io.Serializable {
+		private static final long serialVersionUID = 1L;
+
+		private List<RangerAccessTypeDef> accessTypes;
+		private List<RangerResourceDef>   resources;
+
+
+		public RangerRowFilterDef() {
+			setAccessTypes(null);
+			setResources(null);
+		}
+
+		public RangerRowFilterDef(List<RangerAccessTypeDef> accessTypes, List<RangerResourceDef> resources) {
+			setAccessTypes(accessTypes);
+			setResources(resources);
+		}
+
+		public RangerRowFilterDef(RangerRowFilterDef other) {
+			setAccessTypes(other.getAccessTypes());
+			setResources(other.getResources());
+		}
+
+		public List<RangerAccessTypeDef> getAccessTypes() {
+			return accessTypes;
+		}
+
+		public void setAccessTypes(List<RangerAccessTypeDef> accessTypes) {
+			if(this.accessTypes == null) {
+				this.accessTypes = new ArrayList<RangerAccessTypeDef>();
+			}
+
+			if(this.accessTypes == accessTypes) {
+				return;
+			}
+
+			this.accessTypes.clear();
+
+			if(accessTypes != null) {
+				for(RangerAccessTypeDef accessType : accessTypes) {
+					this.accessTypes.add(accessType);
+				}
+			}
+		}
+
+		public List<RangerResourceDef> getResources() {
+			return resources;
+		}
+
+		public void setResources(List<RangerResourceDef> resources) {
+			if(this.resources == null) {
+				this.resources = new ArrayList<RangerResourceDef>();
+			}
+
+			if(this.resources == resources) {
+				return;
+			}
+
+			this.resources.clear();
+
+			if(resources != null) {
+				for(RangerResourceDef resource : resources) {
+					this.resources.add(resource);
+				}
+			}
+		}
+
+		@Override
+		public String toString( ) {
+			StringBuilder sb = new StringBuilder();
+
+			toString(sb);
+
+			return sb.toString();
+		}
+
+		public StringBuilder toString(StringBuilder sb) {
+			sb.append("RangerRowFilterDef={");
+
+			sb.append("accessTypes={");
+			if(accessTypes != null) {
+				for(RangerAccessTypeDef accessType : accessTypes) {
+					if(accessType != null) {
+						accessType.toString(sb).append(" ");
+					}
+				}
+			}
+			sb.append("} ");
+
+			sb.append("resources={");
+			if(resources != null) {
+				for(RangerResourceDef resource : resources) {
+					if(resource != null) {
+						resource.toString(sb).append(" ");
+					}
+				}
+			}
+			sb.append("} ");
+
+			sb.append("}");
+
+			return sb;
+		}
+
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime * result + ((accessTypes == null) ? 0 : accessTypes.hashCode());
+			result = prime * result + ((resources == null) ? 0 : resources.hashCode());
+			return result;
+		}
+
+		@Override
+		public boolean equals(Object obj) {
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			RangerRowFilterDef other = (RangerRowFilterDef) obj;
+
+			if (accessTypes == null) {
+				if (other.accessTypes != null)
+					return false;
+			} else if (!accessTypes.equals(other.accessTypes))
+				return false;
+			if (resources == null) {
+				if (other.resources != null)
+					return false;
+			} else if (!resources.equals(other.resources))
+				return false;
+			return true;
+		}
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
index 101d911..273d61f 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
@@ -250,6 +250,12 @@ public class RangerServiceDefHelper {
 				} else {
 					resourceDefs = null;
 				}
+			} else if(policyType == RangerPolicy.POLICY_TYPE_ROWFILTER) {
+				if(serviceDef.getRowFilterDef() != null) {
+					resourceDefs = serviceDef.getRowFilterDef().getResources();
+				} else {
+					resourceDefs = null;
+				}
 			} else { // unknown policyType; use all resources
 				resourceDefs = serviceDef.getResources();
 			}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
index d19e3d0..e5f1132 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
@@ -51,6 +51,8 @@ public interface RangerPolicyEngine {
 
 	RangerDataMaskResult evalDataMaskPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor);
 
+	RangerRowFilterResult evalRowFilterPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor);
+
 	boolean isAccessAllowed(RangerAccessResource resource, String user, Set<String> userGroups, String accessType);
 
 	boolean isAccessAllowed(Map<String, RangerPolicyResource> resources, String user, Set<String> userGroups, String accessType);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
index 51cab80..e6e9a3a 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
@@ -294,7 +294,7 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 			}
 		}
 
-		// no need to audit if filter/mask is not enabled
+		// no need to audit if mask is not enabled
 		if(! ret.isMaskEnabled()) {
 			ret.setIsAudited(false);
 		}
@@ -311,6 +311,41 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 	}
 
 	@Override
+	public RangerRowFilterResult evalRowFilterPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerPolicyEngineImpl.evalRowFilterPolicies(" + request + ")");
+		}
+
+		RangerRowFilterResult ret = new RangerRowFilterResult(getServiceName(), getServiceDef(), request);
+
+		if(request != null) {
+			List<RangerPolicyEvaluator> evaluators = policyRepository.getRowFilterPolicyEvaluators();
+			for (RangerPolicyEvaluator evaluator : evaluators) {
+				evaluator.evaluate(request, ret);
+
+				if (ret.getIsAccessDetermined() && ret.getIsAuditedDetermined()) {
+					break;
+				}
+			}
+		}
+
+		// no need to audit if filter is not enabled
+		if(! ret.isRowFilterEnabled()) {
+			ret.setIsAudited(false);
+		}
+
+		if (resultProcessor != null) {
+			resultProcessor.processResult(ret);
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerPolicyEngineImpl.evalRowFilterPolicies(" + request + "): " + ret);
+		}
+
+		return ret;
+	}
+
+	@Override
 	public boolean isAccessAllowed(RangerAccessResource resource, String user, Set<String> userGroups, String accessType) {
 		if (LOG.isDebugEnabled()) {
 			LOG.debug("==> RangerPolicyEngineImpl.isAccessAllowed(" + resource + ", " + user + ", " + userGroups + ", " + accessType + ")");

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
index b1463bc..be98f3b 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
@@ -50,6 +50,7 @@ public class RangerPolicyRepository {
     private List<RangerContextEnricher>       contextEnrichers;
     private List<RangerPolicyEvaluator>       policyEvaluators;
     private List<RangerPolicyEvaluator>       dataMaskPolicyEvaluators;
+    private List<RangerPolicyEvaluator>       rowFilterPolicyEvaluators;
     private final Map<String, Boolean>        accessAuditCache;
 
     private final String                      componentServiceName;
@@ -133,6 +134,10 @@ public class RangerPolicyRepository {
         return dataMaskPolicyEvaluators;
     }
 
+    public List<RangerPolicyEvaluator> getRowFilterPolicyEvaluators() {
+        return rowFilterPolicyEvaluators;
+    }
+
     private RangerServiceDef normalizeAccessTypeDefs(RangerServiceDef serviceDef, final String componentType) {
 
         if (serviceDef != null && StringUtils.isNotBlank(componentType)) {
@@ -317,7 +322,8 @@ public class RangerPolicyRepository {
     private void init(RangerPolicyEngineOptions options) {
 
         List<RangerPolicyEvaluator> policyEvaluators = new ArrayList<RangerPolicyEvaluator>();
-        List<RangerPolicyEvaluator> dataMaskPolicyEvaluators = new ArrayList<RangerPolicyEvaluator>();
+        List<RangerPolicyEvaluator> dataMaskPolicyEvaluators  = new ArrayList<RangerPolicyEvaluator>();
+        List<RangerPolicyEvaluator> rowFilterPolicyEvaluators = new ArrayList<RangerPolicyEvaluator>();
 
         for (RangerPolicy policy : policies) {
             if (skipBuildingPolicyEvaluator(policy, options)) {
@@ -331,6 +337,8 @@ public class RangerPolicyRepository {
                     policyEvaluators.add(evaluator);
                 } else if(policy.getPolicyType() == RangerPolicy.POLICY_TYPE_DATAMASK) {
                     dataMaskPolicyEvaluators.add(evaluator);
+                } else if(policy.getPolicyType() == RangerPolicy.POLICY_TYPE_ROWFILTER) {
+                    rowFilterPolicyEvaluators.add(evaluator);
                 } else {
                     LOG.warn("RangerPolicyEngine: ignoring policy id=" + policy.getId() + " - invalid policyType '" + policy.getPolicyType() + "'");
                 }
@@ -342,6 +350,9 @@ public class RangerPolicyRepository {
         Collections.sort(dataMaskPolicyEvaluators);
         this.dataMaskPolicyEvaluators = Collections.unmodifiableList(dataMaskPolicyEvaluators);
 
+        Collections.sort(rowFilterPolicyEvaluators);
+        this.rowFilterPolicyEvaluators = Collections.unmodifiableList(rowFilterPolicyEvaluators);
+
         List<RangerContextEnricher> contextEnrichers = new ArrayList<RangerContextEnricher>();
         if (CollectionUtils.isNotEmpty(this.policyEvaluators)) {
             if (!options.disableContextEnrichers && !CollectionUtils.isEmpty(serviceDef.getContextEnrichers())) {
@@ -370,13 +381,20 @@ public class RangerPolicyRepository {
                 LOG.debug("policy evaluation order: #" + (++order) + " - policy id=" + policy.getId() + "; name=" + policy.getName() + "; evalOrder=" + policyEvaluator.getEvalOrder());
             }
 
-            LOG.debug("datamasking policy evaluation order: " + this.dataMaskPolicyEvaluators.size() + " policies");
-
+            LOG.debug("dataMask policy evaluation order: " + this.dataMaskPolicyEvaluators.size() + " policies");
             order = 0;
             for(RangerPolicyEvaluator policyEvaluator : this.dataMaskPolicyEvaluators) {
                 RangerPolicy policy = policyEvaluator.getPolicy();
 
-                LOG.debug("datamasking policy evaluation order: #" + (++order) + " - policy id=" + policy.getId() + "; name=" + policy.getName() + "; evalOrder=" + policyEvaluator.getEvalOrder());
+                LOG.debug("dataMask policy evaluation order: #" + (++order) + " - policy id=" + policy.getId() + "; name=" + policy.getName() + "; evalOrder=" + policyEvaluator.getEvalOrder());
+            }
+
+            LOG.debug("rowFilter policy evaluation order: " + this.dataMaskPolicyEvaluators.size() + " policies");
+            order = 0;
+            for(RangerPolicyEvaluator policyEvaluator : this.rowFilterPolicyEvaluators) {
+                RangerPolicy policy = policyEvaluator.getPolicy();
+
+                LOG.debug("rowFilter policy evaluation order: #" + (++order) + " - policy id=" + policy.getId() + "; name=" + policy.getName() + "; evalOrder=" + policyEvaluator.getEvalOrder());
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRowFilterResult.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRowFilterResult.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRowFilterResult.java
new file mode 100644
index 0000000..ad82471
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRowFilterResult.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.plugin.policyengine;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+
+
+public class RangerRowFilterResult extends RangerAccessResult {
+	private String filterExpr = null;
+
+
+	public RangerRowFilterResult(final String serviceName, final RangerServiceDef serviceDef, final RangerAccessRequest request) {
+		this(serviceName, serviceDef, request, null);
+	}
+
+	public RangerRowFilterResult(final String serviceName, final RangerServiceDef serviceDef, final RangerAccessRequest request, final RangerPolicy.RangerPolicyItemRowFilterInfo rowFilterInfo) {
+		super(serviceName, serviceDef, request);
+
+		if(rowFilterInfo != null) {
+			setFilterExpr(rowFilterInfo.getFilterExpr());
+		}
+	}
+
+	/**
+	 * @return the filterExpr
+	 */
+	public String getFilterExpr() {
+		return filterExpr;
+	}
+
+	/**
+	 * @param filterExpr the filterExpr to set
+	 */
+	public void setFilterExpr(String filterExpr) {
+		this.filterExpr = filterExpr;
+	}
+
+	public boolean isRowFilterEnabled() {
+		return StringUtils.isNotEmpty(filterExpr);
+	}
+
+	@Override
+	public String toString( ) {
+		StringBuilder sb = new StringBuilder();
+
+		toString(sb);
+
+		return sb.toString();
+	}
+
+	public StringBuilder toString(StringBuilder sb) {
+		sb.append("RangerRowFilterResult={");
+
+		super.toString(sb);
+
+		sb.append("filterExpr={").append(filterExpr).append("} ");
+
+		sb.append("}");
+
+		return sb;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDataMaskPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDataMaskPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDataMaskPolicyItemEvaluator.java
index 62d624c..fbd7977 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDataMaskPolicyItemEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDataMaskPolicyItemEvaluator.java
@@ -18,17 +18,11 @@
  */
 package org.apache.ranger.plugin.policyevaluator;
 
-import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
 
 
 public interface RangerDataMaskPolicyItemEvaluator extends RangerPolicyItemEvaluator {
 	void init();
 
-	RangerDataMaskPolicyItem getPolicyItem();
-
-	String getMaskType();
-
-	String getMaskCondition();
-
-	String getMaskedValue();
+	RangerPolicyItemDataMaskInfo getDataMaskInfo();
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java
index 4583de9..45db7b0 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultDataMaskPolicyItemEvaluator.java
@@ -28,34 +28,16 @@ import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
 
 
 public class RangerDefaultDataMaskPolicyItemEvaluator extends RangerDefaultPolicyItemEvaluator implements RangerDataMaskPolicyItemEvaluator {
+	final private RangerDataMaskPolicyItem dataMaskPolicyItem;
 
 	public RangerDefaultDataMaskPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy, RangerDataMaskPolicyItem policyItem, int policyItemIndex, RangerPolicyEngineOptions options) {
-		super(serviceDef, policy, policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATA_MASKING, policyItemIndex, options);
-	}
-
-	@Override
-	public RangerDataMaskPolicyItem getPolicyItem() {
-		return (RangerDataMaskPolicyItem)policyItem;
-	}
-
-	@Override
-	public String getMaskType() {
-		RangerPolicyItemDataMaskInfo dataMaskInfo = getPolicyItem().getDataMaskInfo();
+		super(serviceDef, policy, policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATAMASK, policyItemIndex, options);
 
-		return dataMaskInfo != null ? dataMaskInfo.getDataMaskType() : null;
+		dataMaskPolicyItem = policyItem;
 	}
 
 	@Override
-	public String getMaskCondition() {
-		RangerPolicyItemDataMaskInfo dataMaskInfo = getPolicyItem().getDataMaskInfo();
-
-		return dataMaskInfo != null ? dataMaskInfo.getConditionExpr() : null;
-	}
-
-	@Override
-	public String getMaskedValue() {
-		RangerPolicyItemDataMaskInfo dataMaskInfo = getPolicyItem().getDataMaskInfo();
-
-		return dataMaskInfo != null ? dataMaskInfo.getValueExpr() : null;
+	public RangerPolicyItemDataMaskInfo getDataMaskInfo() {
+		return dataMaskPolicyItem == null ? null : dataMaskPolicyItem.getDataMaskInfo();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
index b87891f..2b26218 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
@@ -36,7 +36,10 @@ import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemRowFilterInfo;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
@@ -45,6 +48,7 @@ import org.apache.ranger.plugin.policyengine.RangerAccessResult;
 import org.apache.ranger.plugin.policyengine.RangerDataMaskResult;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
 import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo;
+import org.apache.ranger.plugin.policyengine.RangerRowFilterResult;
 import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
 import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
@@ -63,7 +67,8 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 	private List<RangerPolicyItemEvaluator> allowExceptionEvaluators = null;
 	private List<RangerPolicyItemEvaluator> denyExceptionEvaluators  = null;
 	private int                             customConditionsCount    = 0;
-	private List<RangerDataMaskPolicyItemEvaluator> dataMaskEvaluators = null;
+	private List<RangerDataMaskPolicyItemEvaluator>  dataMaskEvaluators  = null;
+	private List<RangerRowFilterPolicyItemEvaluator> rowFilterEvaluators = null;
 	private String perfTag;
 
 	@Override
@@ -105,13 +110,15 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 			denyEvaluators           = createPolicyItemEvaluators(policy, serviceDef, options, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY);
 			allowExceptionEvaluators = createPolicyItemEvaluators(policy, serviceDef, options, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS);
 			denyExceptionEvaluators  = createPolicyItemEvaluators(policy, serviceDef, options, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS);
-			dataMaskEvaluators       = createPolicyItemEvaluators(policy, serviceDef, options, policy.getDataMaskPolicyItems());
+			dataMaskEvaluators       = createDataMaskPolicyItemEvaluators(policy, serviceDef, options, policy.getDataMaskPolicyItems());
+			rowFilterEvaluators      = createRowFilterPolicyItemEvaluators(policy, serviceDef, options, policy.getRowFilterPolicyItems());
 		} else {
 			allowEvaluators          = Collections.<RangerPolicyItemEvaluator>emptyList();
 			denyEvaluators           = Collections.<RangerPolicyItemEvaluator>emptyList();
 			allowExceptionEvaluators = Collections.<RangerPolicyItemEvaluator>emptyList();
 			denyExceptionEvaluators  = Collections.<RangerPolicyItemEvaluator>emptyList();
 			dataMaskEvaluators       = Collections.<RangerDataMaskPolicyItemEvaluator>emptyList();
+			rowFilterEvaluators      = Collections.<RangerRowFilterPolicyItemEvaluator>emptyList();
 		}
 
 		Collections.sort(allowEvaluators);
@@ -119,8 +126,9 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		Collections.sort(allowExceptionEvaluators);
 		Collections.sort(denyExceptionEvaluators);
 
-		/* dataMask policyItems must be evaulated in the order given in the policy; hence no sort
+		/* dataMask, rowFilter policyItems must be evaulated in the order given in the policy; hence no sort
 		Collections.sort(dataMaskEvaluators);
+		Collections.sort(rowFilterEvaluators);
 		*/
 
 		RangerPerfTracer.log(perf);
@@ -206,63 +214,135 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
         }
     }
 
-    protected void evaluatePolicyItems(RangerAccessRequest request, RangerAccessResult result, boolean isResourceMatch) {
-        if(LOG.isDebugEnabled()) {
-            LOG.debug("==> RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ", " + isResourceMatch + ")");
-        }
+	@Override
+	public void evaluate(RangerAccessRequest request, RangerDataMaskResult result) {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerDefaultPolicyEvaluator.evaluate(" + request + ", " + result + ")");
+		}
 
-        RangerPolicyItemEvaluator matchedPolicyItem = getMatchingPolicyItem(request, denyEvaluators, denyExceptionEvaluators);
+		RangerPerfTracer perf = null;
 
-        if(matchedPolicyItem == null && !result.getIsAllowed()) { // if not denied, evaluate allowItems only if not already allowed
-            matchedPolicyItem = getMatchingPolicyItem(request, allowEvaluators, allowExceptionEvaluators);
-        }
+		if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) {
+			perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, "RangerPolicyEvaluator.evaluate(requestHashCode=" + Integer.toHexString(System.identityHashCode(request)) + "," + perfTag + ")");
+		}
 
-        if(matchedPolicyItem != null) {
-            RangerPolicy policy = getPolicy();
+		if (request != null && result != null && CollectionUtils.isNotEmpty(dataMaskEvaluators)) {
+			boolean isResourceMatchAttempted     = false;
+			boolean isResourceMatch              = false;
+			boolean isResourceHeadMatch          = false;
+			boolean isResourceHeadMatchAttempted = false;
+			final boolean attemptResourceHeadMatch = request.isAccessTypeAny() || request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS;
 
-            if(matchedPolicyItem.getPolicyItemType() == RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY) {
-                if(isResourceMatch) {
-                    result.setIsAllowed(false);
-                    result.setPolicyId(policy.getId());
-                    result.setReason(matchedPolicyItem.getComments());
-                }
-            } else {
-                if(! result.getIsAllowed()) { // if access is not yet allowed by another policy
-                    result.setIsAllowed(true);
-                    result.setPolicyId(policy.getId());
-                    result.setReason(matchedPolicyItem.getComments());
-                }
-            }
-        }
+			if (!result.getIsAuditedDetermined()) {
+				if (!isResourceMatchAttempted) {
+					isResourceMatch = isMatch(request.getResource());
+					isResourceMatchAttempted = true;
+				}
 
-        if(LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ", " + isResourceMatch + ")");
-        }
-    }
+				if (!isResourceMatch) {
+					if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
+						isResourceHeadMatch = matchResourceHead(request.getResource());
+						isResourceHeadMatchAttempted = true;
+					}
+				}
 
-    protected RangerPolicyItemEvaluator getDeterminingPolicyItem(String user, Set<String> userGroups, String accessType) {
-        if(LOG.isDebugEnabled()) {
-            LOG.debug("==> RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + userGroups + ", " + accessType + ")");
-        }
+				if (isResourceMatch || isResourceHeadMatch) {
+					if (isAuditEnabled()) {
+						result.setIsAudited(true);
+					}
+				}
+			}
 
-        RangerPolicyItemEvaluator ret = null;
+			if (!result.getIsAccessDetermined()) {
+				if (!isResourceMatchAttempted) {
+					isResourceMatch = isMatch(request.getResource());
+					isResourceMatchAttempted = true;
+				}
 
-        /*
-         *  1. if a deny matches without hitting any deny-exception, return that
-         *  2. if an allow matches without hitting any allow-exception, return that
-         */
-        ret = getMatchingPolicyItem(user, userGroups, accessType, denyEvaluators, denyExceptionEvaluators);
+				if (!isResourceMatch) {
+					if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
+						isResourceHeadMatch = matchResourceHead(request.getResource());
+						isResourceHeadMatchAttempted = true;
+					}
+				}
 
-        if(ret == null) {
-            ret = getMatchingPolicyItem(user, userGroups, accessType, allowEvaluators, allowExceptionEvaluators);
-        }
+				if (isResourceMatch || isResourceHeadMatch) {
+					evaluatePolicyItems(request, result);
+				}
+			}
+		}
 
-        if(LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + userGroups + ", " + accessType + "): " + ret);
-        }
+		RangerPerfTracer.log(perf);
 
-        return ret;
-    }
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerDefaultPolicyEvaluator.evaluate(" + request + ", " + result + ")");
+		}
+	}
+
+	@Override
+	public void evaluate(RangerAccessRequest request, RangerRowFilterResult result) {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerDefaultPolicyEvaluator.evaluate(" + request + ", " + result + ")");
+		}
+
+		RangerPerfTracer perf = null;
+
+		if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) {
+			perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, "RangerPolicyEvaluator.evaluate(requestHashCode=" + Integer.toHexString(System.identityHashCode(request)) + "," + perfTag + ")");
+		}
+
+		if (request != null && result != null && CollectionUtils.isNotEmpty(rowFilterEvaluators)) {
+			boolean isResourceMatchAttempted     = false;
+			boolean isResourceMatch              = false;
+			boolean isResourceHeadMatch          = false;
+			boolean isResourceHeadMatchAttempted = false;
+			final boolean attemptResourceHeadMatch = request.isAccessTypeAny() || request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS;
+
+			if (!result.getIsAuditedDetermined()) {
+				if (!isResourceMatchAttempted) {
+					isResourceMatch = isMatch(request.getResource());
+					isResourceMatchAttempted = true;
+				}
+
+				if (!isResourceMatch) {
+					if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
+						isResourceHeadMatch = matchResourceHead(request.getResource());
+						isResourceHeadMatchAttempted = true;
+					}
+				}
+
+				if (isResourceMatch || isResourceHeadMatch) {
+					if (isAuditEnabled()) {
+						result.setIsAudited(true);
+					}
+				}
+			}
+
+			if (!result.getIsAccessDetermined()) {
+				if (!isResourceMatchAttempted) {
+					isResourceMatch = isMatch(request.getResource());
+					isResourceMatchAttempted = true;
+				}
+
+				if (!isResourceMatch) {
+					if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
+						isResourceHeadMatch = matchResourceHead(request.getResource());
+						isResourceHeadMatchAttempted = true;
+					}
+				}
+
+				if (isResourceMatch || isResourceHeadMatch) {
+					evaluatePolicyItems(request, result);
+				}
+			}
+		}
+
+		RangerPerfTracer.log(perf);
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerDefaultPolicyEvaluator.evaluate(" + request + ", " + result + ")");
+		}
+	}
 
 	@Override
 	public boolean isMatch(RangerAccessResource resource) {
@@ -419,6 +499,112 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 	}
 
 
+	protected void evaluatePolicyItems(RangerAccessRequest request, RangerAccessResult result, boolean isResourceMatch) {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ", " + isResourceMatch + ")");
+		}
+
+		RangerPolicyItemEvaluator matchedPolicyItem = getMatchingPolicyItem(request, denyEvaluators, denyExceptionEvaluators);
+
+		if(matchedPolicyItem == null && !result.getIsAllowed()) { // if not denied, evaluate allowItems only if not already allowed
+			matchedPolicyItem = getMatchingPolicyItem(request, allowEvaluators, allowExceptionEvaluators);
+		}
+
+		if(matchedPolicyItem != null) {
+			RangerPolicy policy = getPolicy();
+
+			if(matchedPolicyItem.getPolicyItemType() == RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY) {
+				if(isResourceMatch) {
+					result.setIsAllowed(false);
+					result.setPolicyId(policy.getId());
+					result.setReason(matchedPolicyItem.getComments());
+				}
+			} else {
+				if(! result.getIsAllowed()) { // if access is not yet allowed by another policy
+					result.setIsAllowed(true);
+					result.setPolicyId(policy.getId());
+					result.setReason(matchedPolicyItem.getComments());
+				}
+			}
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ", " + isResourceMatch + ")");
+		}
+	}
+
+	protected void evaluatePolicyItems(RangerAccessRequest request, RangerDataMaskResult result) {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ")");
+		}
+
+		RangerDataMaskPolicyItemEvaluator matchedPolicyItem = getMatchingPolicyItem(request, dataMaskEvaluators);
+		RangerPolicyItemDataMaskInfo      dataMaskInfo      = matchedPolicyItem != null ? matchedPolicyItem.getDataMaskInfo() : null;
+
+		if(dataMaskInfo != null) {
+			RangerPolicy policy = getPolicy();
+
+			result.setIsAllowed(true);
+			result.setIsAccessDetermined(true);
+
+			result.setMaskType(dataMaskInfo.getDataMaskType());
+			result.setMaskCondition(dataMaskInfo.getConditionExpr());
+			result.setMaskedValue(dataMaskInfo.getValueExpr());
+			result.setPolicyId(policy.getId());
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ", " + ")");
+		}
+	}
+
+	protected void evaluatePolicyItems(RangerAccessRequest request, RangerRowFilterResult result) {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ")");
+		}
+
+		RangerRowFilterPolicyItemEvaluator matchedPolicyItem = getMatchingPolicyItem(request, rowFilterEvaluators);
+		RangerPolicyItemRowFilterInfo      rowFilterInfo     = matchedPolicyItem != null ? matchedPolicyItem.getRowFilterInfo() : null;
+
+		if(rowFilterInfo != null) {
+			RangerPolicy policy = getPolicy();
+
+			result.setIsAllowed(true);
+			result.setIsAccessDetermined(true);
+
+			result.setFilterExpr(rowFilterInfo.getFilterExpr());
+			result.setPolicyId(policy.getId());
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ", " + ")");
+		}
+	}
+
+	protected RangerPolicyItemEvaluator getDeterminingPolicyItem(String user, Set<String> userGroups, String accessType) {
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + userGroups + ", " + accessType + ")");
+		}
+
+		RangerPolicyItemEvaluator ret = null;
+
+		/*
+		 *  1. if a deny matches without hitting any deny-exception, return that
+		 *  2. if an allow matches without hitting any allow-exception, return that
+		 */
+		ret = getMatchingPolicyItem(user, userGroups, accessType, denyEvaluators, denyExceptionEvaluators);
+
+		if(ret == null) {
+			ret = getMatchingPolicyItem(user, userGroups, accessType, allowEvaluators, allowExceptionEvaluators);
+		}
+
+		if(LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerDefaultPolicyEvaluator.getDeterminingPolicyItem(" + user + ", " + userGroups + ", " + accessType + "): " + ret);
+		}
+
+		return ret;
+	}
+
 	private void getResourceAccessInfo(RangerAccessRequest request, List<? extends RangerPolicyItemEvaluator> policyItems, Set<String> users, Set<String> groups) {
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("==> RangerDefaultPolicyEvaluator.getResourceAccessInfo(" + request + ", " + policyItems + ", " + users + ", " + groups + ")");
@@ -668,6 +854,58 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		return ret;
 	}
 
+	private List<RangerDataMaskPolicyItemEvaluator> createDataMaskPolicyItemEvaluators(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options, List<RangerDataMaskPolicyItem> policyItems) {
+		List<RangerDataMaskPolicyItemEvaluator> ret = null;
+
+		if(CollectionUtils.isNotEmpty(policyItems)) {
+			ret = new ArrayList<RangerDataMaskPolicyItemEvaluator>();
+
+			int policyItemCounter = 1;
+
+			for(RangerDataMaskPolicyItem policyItem : policyItems) {
+				RangerDataMaskPolicyItemEvaluator itemEvaluator = new RangerDefaultDataMaskPolicyItemEvaluator(serviceDef, policy, policyItem, policyItemCounter++, options);
+
+				itemEvaluator.init();
+
+				ret.add(itemEvaluator);
+
+				if(CollectionUtils.isNotEmpty(itemEvaluator.getConditionEvaluators())) {
+					customConditionsCount += itemEvaluator.getConditionEvaluators().size();
+				}
+			}
+		} else {
+			ret = Collections.<RangerDataMaskPolicyItemEvaluator>emptyList();
+		}
+
+		return ret;
+	}
+
+	private List<RangerRowFilterPolicyItemEvaluator> createRowFilterPolicyItemEvaluators(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options, List<RangerRowFilterPolicyItem> policyItems) {
+		List<RangerRowFilterPolicyItemEvaluator> ret = null;
+
+		if(CollectionUtils.isNotEmpty(policyItems)) {
+			ret = new ArrayList<RangerRowFilterPolicyItemEvaluator>();
+
+			int policyItemCounter = 1;
+
+			for(RangerRowFilterPolicyItem policyItem : policyItems) {
+				RangerRowFilterPolicyItemEvaluator itemEvaluator = new RangerDefaultRowFilterPolicyItemEvaluator(serviceDef, policy, policyItem, policyItemCounter++, options);
+
+				itemEvaluator.init();
+
+				ret.add(itemEvaluator);
+
+				if(CollectionUtils.isNotEmpty(itemEvaluator.getConditionEvaluators())) {
+					customConditionsCount += itemEvaluator.getConditionEvaluators().size();
+				}
+			}
+		} else {
+			ret = Collections.<RangerRowFilterPolicyItemEvaluator>emptyList();
+		}
+
+		return ret;
+	}
+
 	private boolean isPolicyItemTypeEnabled(RangerServiceDef serviceDef, int policyItemType) {
 		boolean ret = true;
 
@@ -680,15 +918,21 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		return ret;
 	}
 
-	private RangerPolicyItemEvaluator getMatchingPolicyItem(RangerAccessRequest request, List<? extends RangerPolicyItemEvaluator> evaluators, List<? extends RangerPolicyItemEvaluator> exceptionEvaluators) {
+	protected <T extends RangerPolicyItemEvaluator> T getMatchingPolicyItem(RangerAccessRequest request, List<T> evaluators) {
+		T ret = getMatchingPolicyItem(request, evaluators, null);
+
+		return ret;
+	}
+
+	private <T extends RangerPolicyItemEvaluator> T getMatchingPolicyItem(RangerAccessRequest request, List<T> evaluators, List<T> exceptionEvaluators) {
         if(LOG.isDebugEnabled()) {
             LOG.debug("==> RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + request + ")");
         }
 
-        RangerPolicyItemEvaluator ret = null;
+        T ret = null;
 
         if(CollectionUtils.isNotEmpty(evaluators)) {
-            for (RangerPolicyItemEvaluator evaluator : evaluators) {
+            for (T evaluator : evaluators) {
                 if(evaluator.isMatch(request)) {
                     ret = evaluator;
 
@@ -698,7 +942,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
         }
 
         if(ret != null && CollectionUtils.isNotEmpty(exceptionEvaluators)) {
-            for (RangerPolicyItemEvaluator exceptionEvaluator : exceptionEvaluators) {
+            for (T exceptionEvaluator : exceptionEvaluators) {
                 if(exceptionEvaluator.isMatch(request)) {
                     if(LOG.isDebugEnabled()) {
                         LOG.debug("RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + request + "): found exception policyItem(" + exceptionEvaluator.getPolicyItem() + "); ignoring the matchedPolicyItem(" + ret.getPolicyItem() + ")");
@@ -718,15 +962,15 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
         return ret;
     }
 
-	private RangerPolicyItemEvaluator getMatchingPolicyItem(String user, Set<String> userGroups, String accessType, List<RangerPolicyItemEvaluator> evaluators, List<RangerPolicyItemEvaluator> exceptionEvaluators) {
+	private <T extends RangerPolicyItemEvaluator> T getMatchingPolicyItem(String user, Set<String> userGroups, String accessType, List<T> evaluators, List<T> exceptionEvaluators) {
         if(LOG.isDebugEnabled()) {
             LOG.debug("==> RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + user + ", " + userGroups + ", " + accessType + ")");
         }
 
-        RangerPolicyItemEvaluator ret = null;
+        T ret = null;
 
         if(CollectionUtils.isNotEmpty(evaluators)) {
-            for (RangerPolicyItemEvaluator evaluator : evaluators) {
+            for (T evaluator : evaluators) {
                 if(evaluator.matchUserGroup(user, userGroups) && evaluator.matchAccessType(accessType)) {
                     ret = evaluator;
 
@@ -736,7 +980,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
         }
 
         if(ret != null && CollectionUtils.isNotEmpty(exceptionEvaluators)) {
-            for (RangerPolicyItemEvaluator exceptionEvaluator : exceptionEvaluators) {
+            for (T exceptionEvaluator : exceptionEvaluators) {
                 if(exceptionEvaluator.matchUserGroup(user, userGroups) && exceptionEvaluator.matchAccessType(accessType)) {
                     if(LOG.isDebugEnabled()) {
                         LOG.debug("RangerDefaultPolicyEvaluator.getMatchingPolicyItem(" + user + ", " + userGroups + ", " + accessType + "): found exception policyItem(" + exceptionEvaluator.getPolicyItem() + "); ignoring the matchedPolicyItem(" + ret.getPolicyItem() + ")");
@@ -771,114 +1015,4 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 
 		return ret;
 	}
-
-	@Override
-	public void evaluate(RangerAccessRequest request, RangerDataMaskResult result) {
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyEvaluator.evaluate(" + request + ", " + result + ")");
-		}
-
-		RangerPerfTracer perf = null;
-
-		if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) {
-			perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, "RangerPolicyEvaluator.evaluate(requestHashCode=" + Integer.toHexString(System.identityHashCode(request)) + "," + perfTag + ")");
-		}
-
-		if (request != null && result != null && CollectionUtils.isNotEmpty(dataMaskEvaluators)) {
-			boolean isResourceMatchAttempted = false;
-			boolean isResourceMatch          = false;
-
-			if (!result.getIsAuditedDetermined()) {
-				if (!isResourceMatchAttempted) {
-					isResourceMatch = isMatch(request.getResource());
-					isResourceMatchAttempted = true;
-				}
-
-				if (isResourceMatch) {
-					if (isAuditEnabled()) {
-						result.setIsAudited(true);
-					}
-				}
-			}
-
-			if (!result.getIsAccessDetermined()) {
-				if (!isResourceMatchAttempted) {
-					isResourceMatch = isMatch(request.getResource());
-					isResourceMatchAttempted = true;
-				}
-
-				if (isResourceMatch) {
-					evaluatePolicyItems(request, result);
-				}
-			}
-		}
-
-		RangerPerfTracer.log(perf);
-
-        if(LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerDefaultPolicyEvaluator.evaluate(" + request + ", " + result + ")");
-        }
-	}
-
-	protected void evaluatePolicyItems(RangerAccessRequest request, RangerDataMaskResult result) {
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ")");
-		}
-
-		RangerDataMaskPolicyItemEvaluator matchedPolicyItem = getMatchingPolicyItem(request, dataMaskEvaluators);
-
-		if(matchedPolicyItem != null) {
-			RangerPolicy policy = getPolicy();
-
-			result.setIsAllowed(true);
-			result.setIsAccessDetermined(true);
-
-			result.setMaskType(matchedPolicyItem.getMaskType());
-			result.setMaskCondition(matchedPolicyItem.getMaskCondition());
-			result.setMaskedValue(matchedPolicyItem.getMaskedValue());
-			result.setPolicyId(policy.getId());
-		}
-
-		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyEvaluator.evaluatePolicyItems(" + request + ", " + result + ", " + ")");
-		}
-	}
-
-	protected RangerDataMaskPolicyItemEvaluator getMatchingPolicyItem(RangerAccessRequest request, List<RangerDataMaskPolicyItemEvaluator> evaluators) {
-		RangerDataMaskPolicyItemEvaluator ret = null;
-
-		RangerPolicyItemEvaluator policyItem = getMatchingPolicyItem(request, dataMaskEvaluators, null);
-
-		if(policyItem != null) {
-			ret = (RangerDataMaskPolicyItemEvaluator)policyItem;
-		}
-
-		return ret;
-	}
-
-	private List<RangerDataMaskPolicyItemEvaluator> createPolicyItemEvaluators(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options, List<RangerDataMaskPolicyItem> policyItems) {
-		List<RangerDataMaskPolicyItemEvaluator> ret = null;
-
-		if(CollectionUtils.isNotEmpty(policyItems)) {
-			ret = new ArrayList<RangerDataMaskPolicyItemEvaluator>();
-
-			int policyItemCounter = 1;
-
-			for(RangerDataMaskPolicyItem policyItem : policyItems) {
-				RangerDataMaskPolicyItemEvaluator itemEvaluator = new RangerDefaultDataMaskPolicyItemEvaluator(serviceDef, policy, policyItem, policyItemCounter++, options);
-
-				itemEvaluator.init();
-
-				ret.add(itemEvaluator);
-
-				if(CollectionUtils.isNotEmpty(itemEvaluator.getConditionEvaluators())) {
-					customConditionsCount += itemEvaluator.getConditionEvaluators().size();
-				}
-			}
-		} else {
-			ret = Collections.<RangerDataMaskPolicyItemEvaluator>emptyList();
-		}
-
-		return ret;
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
new file mode 100644
index 0000000..365661b
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultRowFilterPolicyItemEvaluator.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.plugin.policyevaluator;
+
+
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemRowFilterInfo;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
+
+
+public class RangerDefaultRowFilterPolicyItemEvaluator extends RangerDefaultPolicyItemEvaluator implements RangerRowFilterPolicyItemEvaluator {
+	final private RangerRowFilterPolicyItem rowFilterPolicyItem;
+
+	public RangerDefaultRowFilterPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy, RangerRowFilterPolicyItem policyItem, int policyItemIndex, RangerPolicyEngineOptions options) {
+		super(serviceDef, policy, policyItem, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATAMASK, policyItemIndex, options);
+
+		rowFilterPolicyItem = policyItem;
+	}
+
+	@Override
+	public RangerPolicyItemRowFilterInfo getRowFilterInfo() {
+		return rowFilterPolicyItem == null ? null : rowFilterPolicyItem.getRowFilterInfo();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
index 1010727..be97830 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
@@ -32,6 +32,7 @@ import org.apache.ranger.plugin.policyengine.RangerAccessResource;
 import org.apache.ranger.plugin.policyengine.RangerDataMaskResult;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
 import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo;
+import org.apache.ranger.plugin.policyengine.RangerRowFilterResult;
 
 
 public interface RangerPolicyEvaluator extends Comparable<RangerPolicyEvaluator> {
@@ -59,6 +60,8 @@ public interface RangerPolicyEvaluator extends Comparable<RangerPolicyEvaluator>
 
 	void evaluate(RangerAccessRequest request, RangerDataMaskResult result);
 
+	void evaluate(RangerAccessRequest request, RangerRowFilterResult result);
+
 	boolean isMatch(RangerAccessResource resource);
 
 	boolean isCompleteMatch(RangerAccessResource resource);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
index 3c4b926..80e46f5 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
@@ -30,7 +30,8 @@ public interface RangerPolicyItemEvaluator extends Comparable<RangerPolicyItemEv
 	int POLICY_ITEM_TYPE_DENY             = 1;
 	int POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS = 2;
 	int POLICY_ITEM_TYPE_DENY_EXCEPTIONS  = 3;
-	int POLICY_ITEM_TYPE_DATA_MASKING     = 4;
+	int POLICY_ITEM_TYPE_DATAMASK         = 4;
+	int POLICY_ITEM_TYPE_ROWFILTER        = 5;
 
 	void init();
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerRowFilterPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerRowFilterPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerRowFilterPolicyItemEvaluator.java
new file mode 100644
index 0000000..c108e4f
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerRowFilterPolicyItemEvaluator.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.plugin.policyevaluator;
+
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemRowFilterInfo;
+
+
+public interface RangerRowFilterPolicyItemEvaluator extends RangerPolicyItemEvaluator {
+	void init();
+
+	RangerPolicyItemRowFilterInfo getRowFilterInfo();
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
index aef7bcb..bf5e95b 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
@@ -194,6 +194,18 @@ public class RangerBasePlugin {
 		return null;
 	}
 
+	public RangerRowFilterResult evalRowFilterPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor) {
+		RangerPolicyEngine policyEngine = this.policyEngine;
+
+		if(policyEngine != null) {
+			policyEngine.preProcess(request);
+
+			return policyEngine.evalRowFilterPolicies(request, resultProcessor);
+		}
+
+		return null;
+	}
+
 	public RangerResourceAccessInfo getResourceAccessInfo(RangerAccessRequest request) {
 		RangerPolicyEngine policyEngine = this.policyEngine;
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
index b154115..478ea0c 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
@@ -451,7 +451,9 @@ public class AbstractPredicateUtil {
 					List<?>[] policyItemsList = new List<?>[] { policy.getPolicyItems(),
 																policy.getDenyPolicyItems(),
 																policy.getAllowExceptions(),
-																policy.getDenyExceptions()
+																policy.getDenyExceptions(),
+																policy.getDataMaskPolicyItems(),
+																policy.getRowFilterPolicyItems()
 															  };
 
 					for(List<?> policyItemsObj : policyItemsList) {
@@ -501,7 +503,9 @@ public class AbstractPredicateUtil {
 					List<?>[] policyItemsList = new List<?>[] { policy.getPolicyItems(),
 							policy.getDenyPolicyItems(),
 							policy.getAllowExceptions(),
-							policy.getDenyExceptions()
+							policy.getDenyExceptions(),
+							policy.getDataMaskPolicyItems(),
+							policy.getRowFilterPolicyItems()
 						  };
 
 					for(List<?> policyItemsObj : policyItemsList) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
index 34f4cc6..eaf60b7 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
@@ -68,6 +68,7 @@ public class ServiceDefUtil {
 
     public static RangerServiceDef normalize(RangerServiceDef serviceDef) {
         normalizeDataMaskDef(serviceDef);
+        normalizeRowFilterDef(serviceDef);
 
         return serviceDef;
     }
@@ -119,6 +120,53 @@ public class ServiceDefUtil {
         }
     }
 
+    private static void normalizeRowFilterDef(RangerServiceDef serviceDef) {
+        if(serviceDef != null && serviceDef.getRowFilterDef() != null) {
+            List<RangerResourceDef>   rowFilterResources   = serviceDef.getRowFilterDef().getResources();
+            List<RangerAccessTypeDef> rowFilterAccessTypes = serviceDef.getRowFilterDef().getAccessTypes();
+
+            if(CollectionUtils.isNotEmpty(rowFilterResources)) {
+                List<RangerResourceDef> resources     = serviceDef.getResources();
+                List<RangerResourceDef> processedDefs = new ArrayList<RangerResourceDef>(rowFilterResources.size());
+
+                for(RangerResourceDef rowFilterResource : rowFilterResources) {
+                    RangerResourceDef processedDef = rowFilterResource;
+
+                    for(RangerResourceDef resourceDef : resources) {
+                        if(StringUtils.equals(resourceDef.getName(), rowFilterResource.getName())) {
+                            processedDef = ServiceDefUtil.mergeResourceDef(resourceDef, rowFilterResource);
+                            break;
+                        }
+                    }
+
+                    processedDefs.add(processedDef);
+                }
+
+                serviceDef.getRowFilterDef().setResources(processedDefs);
+            }
+
+            if(CollectionUtils.isNotEmpty(rowFilterAccessTypes)) {
+                List<RangerAccessTypeDef> accessTypes   = serviceDef.getAccessTypes();
+                List<RangerAccessTypeDef> processedDefs = new ArrayList<RangerAccessTypeDef>(accessTypes.size());
+
+                for(RangerAccessTypeDef rowFilterAccessType : rowFilterAccessTypes) {
+                    RangerAccessTypeDef processedDef = rowFilterAccessType;
+
+                    for(RangerAccessTypeDef accessType : accessTypes) {
+                        if(StringUtils.equals(accessType.getName(), rowFilterAccessType.getName())) {
+                            processedDef = ServiceDefUtil.mergeAccessTypeDef(accessType, rowFilterAccessType);
+                            break;
+                        }
+                    }
+
+                    processedDefs.add(processedDef);
+                }
+
+                serviceDef.getRowFilterDef().setAccessTypes(processedDefs);
+            }
+        }
+    }
+
     private static RangerResourceDef mergeResourceDef(RangerResourceDef base, RangerResourceDef delta) {
         RangerResourceDef ret = new RangerResourceDef(base);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
----------------------------------------------------------------------
diff --git a/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
index f3c75d1..8cdf273 100644
--- a/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
@@ -223,7 +223,6 @@
 		"description": "List of Hive resources"
 	  }
 	],
-
 	"dataMaskDef": {
 		"accessTypes": [
 			{
@@ -347,7 +346,7 @@
 			},
 			{
 				"itemId": 10,
-				"name": "MASK_DATE_YEAR",
+				"name": "MASK_DATE_SHOW_YEAR",
 				"label": "Date: show only year",
 				"description": "Date: show only year",
 				"transformer": "org.apache.ranger.authorization.hive.udf.MaskTransformer",
@@ -368,5 +367,32 @@
 				"description": "No masking"
 			}
 		]
+	},
+	"rowFilterDef": {
+		"accessTypes": [
+			{
+				"name": "select"
+			}
+		],
+		"resources": [
+			{
+				"name": "database",
+				"matcherOptions": {
+					"wildCard": "false"
+				},
+				"lookupSupported": true,
+				"mandatory": true,
+				"uiHint": "{ \"singleValue\":true }"
+			},
+			{
+				"name": "table",
+				"matcherOptions": {
+					"wildCard": "false"
+				},
+				"lookupSupported": true,
+				"mandatory": true,
+				"uiHint": "{ \"singleValue\":true }"
+			}
+		]
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
----------------------------------------------------------------------
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
index 05cbcde..8ee6bea 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
@@ -203,7 +203,7 @@ public class TestPolicyEngine {
 
 	@Test
 	public void testPolicyEngine_hiveMasking() {
-		String[] resourceFiles = { "/policyengine/test_policyengine_hive_masking.json" };
+		String[] resourceFiles = {"/policyengine/test_policyengine_hive_mask_filter.json"};
 
 		runTestsFromResourceFiles(resourceFiles);
 	}
@@ -339,6 +339,15 @@ public class TestPolicyEngine {
 				assertEquals("policyId mismatched! - " + test.name, expected.getPolicyId(), result.getPolicyId());
 			}
 
+			if(test.rowFilterResult != null) {
+				RangerRowFilterResult expected = test.rowFilterResult;
+				RangerRowFilterResult result   = policyEngine.evalRowFilterPolicies(request, auditHandler);
+
+				assertNotNull("result was null! - " + test.name, result);
+				assertEquals("filterExpr mismatched! - " + test.name, expected.getFilterExpr(), result.getFilterExpr());
+				assertEquals("policyId mismatched! - " + test.name, expected.getPolicyId(), result.getPolicyId());
+			}
+
 			if(test.resourceAccessInfo != null) {
 				RangerResourceAccessInfo expected = new RangerResourceAccessInfo(test.resourceAccessInfo);
 				RangerResourceAccessInfo result   = policyEngine.getResourceAccessInfo(test.request);
@@ -363,7 +372,8 @@ public class TestPolicyEngine {
 			public String              name;
 			public RangerAccessRequest request;
 			public RangerAccessResult  result;
-			public RangerDataMaskResult dataMaskResult;
+			public RangerDataMaskResult  dataMaskResult;
+			public RangerRowFilterResult rowFilterResult;
 			public RangerResourceAccessInfo resourceAccessInfo;
 		}
 


[2/3] incubator-ranger git commit: RANGER-908: Ranger policy model updated to support row-filtering

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/test/resources/policyengine/test_policyengine_hive_mask_filter.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_hive_mask_filter.json b/agents-common/src/test/resources/policyengine/test_policyengine_hive_mask_filter.json
new file mode 100644
index 0000000..d3e0c25
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_hive_mask_filter.json
@@ -0,0 +1,243 @@
+{
+  "serviceName":"hivedev",
+
+  "serviceDef":{
+    "name":"hive",
+    "id":3,
+    "resources":[
+      {"name":"database","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Database","description":"Hive Database"},
+      {"name":"table","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Table","description":"Hive Table"},
+      {"name":"udf","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive UDF","description":"Hive UDF"},
+      {"name":"column","level":3,"parent":"table","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Column","description":"Hive Column"}
+    ],
+    "accessTypes":[
+      {"name":"select","label":"Select"},
+      {"name":"update","label":"Update"},
+      {"name":"create","label":"Create"},
+      {"name":"drop","label":"Drop"},
+      {"name":"alter","label":"Alter"},
+      {"name":"index","label":"Index"},
+      {"name":"lock","label":"Lock"},
+      {"name":"all","label":"All",
+        "impliedGrants": [
+          "select",
+          "update",
+          "create",
+          "drop",
+          "alter",
+          "index",
+          "lock"
+        ]
+      }
+    ],
+    "dataMaskDef": {
+      "maskTypes": [
+        {
+          "itemId": 1,
+          "name": "MASK",
+          "label": "Mask",
+          "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'"
+        },
+        {
+          "itemId": 2,
+          "name": "SHUFFLE",
+          "label": "Shuffle",
+          "description": "Randomly shuffle the contents"
+        },
+        {
+          "itemId": 10,
+          "name": "NULL",
+          "label": "NULL",
+          "description": "Replace with NULL"
+        }
+
+      ],
+      "accessTypes":[
+        {"name":"select","label":"Select"}
+      ],
+      "resources":[
+        {"name":"database","matcherOptions":{"wildCard":false}},
+        {"name":"table","matcherOptions":{"wildCard":false}},
+        {"name":"column","matcherOptions":{"wildCard":false}}
+      ]
+    },
+    "rowFilterDef": {
+      "accessTypes":[
+        {"name":"select","label":"Select"}
+      ],
+      "resources":[
+        {"name":"database","matcherOptions":{"wildCard":false}},
+        {"name":"table","matcherOptions":{"wildCard":false}}
+      ]
+    }
+  },
+
+  "policies":[
+    {"id":1,"name":"db=*: audit-all-access","isEnabled":true,"isAuditEnabled":true,
+     "resources":{"database":{"values":["*"]},"table":{"values":["*"]},"column":{"values":["*"]}},
+     "policyItems":[
+       {"accesses":[{"type":"all","isAllowed":true}],"users":["hive", "user1", "user2"],"groups":["public"],"delegateAdmin":false}
+     ]
+    },
+    {"id":101,"name":"db=employee, table=personal, column=ssn: mask ssn column","isEnabled":true,"isAuditEnabled":true,"policyType":1,
+      "resources":{"database":{"values":["employee"]},"table":{"values":["personal"]},"column":{"values":["ssn"]}},
+      "dataMaskPolicyItems":[
+        {"accesses":[{"type":"select","isAllowed":true}],"users":["user1"],"groups":[],"delegateAdmin":false,
+         "dataMaskInfo": {"dataMaskType":"MASK"}
+        },
+        {"accesses":[{"type":"select","isAllowed":true}],"users":["user2"],"groups":[],"delegateAdmin":false,
+          "dataMaskInfo": {"dataMaskType":"SHUFFLE"}
+        }
+      ]
+    },
+    {"id":102,"name":"db=hr, table=employee, column=date_of_birth: mask date_of_birth column","isEnabled":true,"isAuditEnabled":true,"policyType":1,
+      "resources":{"database":{"values":["hr"]},"table":{"values":["employee"]},"column":{"values":["date_of_birth"]}},
+      "dataMaskPolicyItems":[
+        {"accesses":[{"type":"select","isAllowed":true}],"users":["user1"],"groups":[],"delegateAdmin":false,
+          "dataMaskInfo": {"dataMaskType":"MASK"}
+        },
+        {"accesses":[{"type":"select","isAllowed":true}],"users":["user2"],"groups":[],"delegateAdmin":false,
+          "dataMaskInfo": {"dataMaskType":"SHUFFLE"}
+        }
+      ]
+    },
+    {"id":201,"name":"db=employee, table=personal","isEnabled":true,"isAuditEnabled":true,"policyType":2,
+      "resources":{"database":{"values":["employee"]},"table":{"values":["personal"]}},
+      "rowFilterPolicyItems":[
+        {"accesses":[{"type":"select","isAllowed":true}],"users":["user1"],"groups":[],"delegateAdmin":false,
+          "rowFilterInfo": {"filterExpr":"location='US'"}
+        },
+        {"accesses":[{"type":"select","isAllowed":true}],"users":["user2"],"groups":[],"delegateAdmin":false,
+          "rowFilterInfo": {"filterExpr":"location='CA'"}
+        }
+      ]
+    },
+    {"id":202,"name":"db=hr, table=employee","isEnabled":true,"isAuditEnabled":true,"policyType":2,
+      "resources":{"database":{"values":["hr"]},"table":{"values":["employee"]}},
+      "rowFilterPolicyItems":[
+        {"accesses":[{"type":"select","isAllowed":true}],"users":["user1"],"groups":[],"delegateAdmin":false,
+          "rowFilterInfo": {"filterExpr":"dept='production'"}
+        },
+        {"accesses":[{"type":"select","isAllowed":true}],"users":["user2"],"groups":[],"delegateAdmin":false,
+          "rowFilterInfo": {"filterExpr":"dept='purchase'"}
+        }
+      ]
+    }
+  ],
+
+  "tests":[
+    {"name":"'select ssn from employee.personal;' for user1 - maskType=MASK",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}},
+        "accessType":"select","user":"user1","userGroups":[],"requestData":"select ssn from employee.personal;' for user1"
+      },
+      "dataMaskResult":{"maskType":"MASK","maskCondition":null,"maskValue":null,"policyId":101}
+    },
+    {"name":"'select ssn from employee.personal;' for user2 - maskType=SHUFFLE",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}},
+        "accessType":"select","user":"user2","userGroups":[],"requestData":"select ssn from employee.personal;' for user2"
+      },
+      "dataMaskResult":{"maskType":"SHUFFLE","maskCondition":null,"maskValue":null,"policyId":101}
+    },
+    {"name":"'select ssn from employee.personal;' for user3 - no-mask",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}},
+        "accessType":"select","user":"user3","userGroups":[],"requestData":"select ssn from employee.personal;' for user3"
+      },
+      "dataMaskResult":{"maskType":null,"maskCondition":null,"maskValue":null,"policyId":-1}
+    },
+    {"name":"'select name from employee.personal;' for user1 - no-mask",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal", "column":"name"}},
+        "accessType":"select","user":"user1","userGroups":[],"requestData":"select name from employee.personal;' for user1"
+      },
+      "dataMaskResult":{"maskType":null,"maskCondition":null,"maskValue":null,"policyId":-1}
+    },
+    {"name":"'select date_of_birth from hr.employee;' for user1 - maskType=MASK",
+      "request":{
+        "resource":{"elements":{"database":"hr", "table":"employee", "column":"date_of_birth"}},
+        "accessType":"select","user":"user1","userGroups":[],"requestData":"select date_of_birth from hr.employee;' for user1"
+      },
+      "dataMaskResult":{"maskType":"MASK","maskCondition":null,"maskValue":null,"policyId":102}
+    },
+    {"name":"'select date_of_birth from hr.employee;' for user2 - maskType=SHUFFLE",
+      "request":{
+        "resource":{"elements":{"database":"hr", "table":"employee", "column":"date_of_birth"}},
+        "accessType":"select","user":"user2","userGroups":[],"requestData":"select date_of_birth from hr.employee2;' for user2"
+      },
+      "dataMaskResult":{"maskType":"SHUFFLE","maskCondition":null,"maskValue":null,"policyId":102}
+    },
+    {"name":"'select date_of_birth1 from hr.employee;' for user1 - no-mask",
+      "request":{
+        "resource":{"elements":{"database":"hr", "table":"employee", "column":"date_of_birth1"}},
+        "accessType":"select","user":"user1","userGroups":[],"requestData":"select date_of_birth1 from hr.employee;' for user1"
+      },
+      "dataMaskResult":{"maskType":null,"maskCondition":null,"maskValue":null,"policyId":-1}
+    },
+    {"name":"'select date_of_birth from hr2.employee2;' for user2 - no-mask",
+      "request":{
+        "resource":{"elements":{"database":"hr2", "table":"employee2", "column":"date_of_birth"}},
+        "accessType":"select","user":"user2","userGroups":[],"requestData":"select date_of_birth from hr2.employee2;' for user2"
+      },
+      "dataMaskResult":{"maskType":null,"maskCondition":null,"maskValue":null,"policyId":-1}
+    },
+    {"name":"'select ssn from employee.personal;' for user1 - filterExpr=location='US'",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal"}},
+        "accessType":"select","user":"user1","userGroups":[],"requestData":"select ssn from employee.personal;' for user1"
+      },
+      "rowFilterResult":{"filterExpr":"location='US'","policyId":201}
+    },
+    {"name":"'select ssn from employee.personal;' for user2 - filterExpr=location='CA'",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal"}},
+        "accessType":"select","user":"user2","userGroups":[],"requestData":"select ssn from employee.personal;' for user2"
+      },
+      "rowFilterResult":{"filterExpr":"location='CA'","policyId":201}
+    },
+    {"name":"'select ssn from employee.personal;' for user3 - no-filter",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal"}},
+        "accessType":"select","user":"user3","userGroups":[],"requestData":"select ssn from employee.personal;' for user3"
+      },
+      "rowFilterResult":{"filterExpr":null,"policyId":-1}
+    },
+    {"name":"'select name from employee.personal;' for group3 - no-filter",
+      "request":{
+        "resource":{"elements":{"database":"employee", "table":"personal"}},
+        "accessType":"select","user":"user5","userGroups":["group3"],"requestData":"select name from employee.personal;' for user5/group3"
+      },
+      "rowFilterResult":{"filterExpr":null,"policyId":-1}
+    },
+    {"name":"'select date_of_birth from hr.employee;' for user1 - filterExpr=dept='production'",
+      "request":{
+        "resource":{"elements":{"database":"hr", "table":"employee"}},
+        "accessType":"select","user":"user1","userGroups":[],"requestData":"select date_of_birth from hr.employee;' for user1"
+      },
+      "rowFilterResult":{"filterExpr":"dept='production'","policyId":202}
+    },
+    {"name":"'select date_of_birth from hr.employee;' for user2 - filterExpr=dept='purchase'",
+      "request":{
+        "resource":{"elements":{"database":"hr", "table":"employee"}},
+        "accessType":"select","user":"user2","userGroups":[],"requestData":"select date_of_birth from hr.employee2;' for user2"
+      },
+      "rowFilterResult":{"filterExpr":"dept='purchase'","policyId":202}
+    },
+    {"name":"'select date_of_birth from hr.employee;' for user3 - no-filter",
+      "request":{
+        "resource":{"elements":{"database":"hr", "table":"employee"}},
+        "accessType":"select","user":"user3","userGroups":[],"requestData":"select date_of_birth from hr.employee;' for user3"
+      },
+      "rowFilterResult":{"filterExpr":null,"policyId":-1}
+    },
+    {"name":"'select date_of_birth from hr2.employee2;' for user2 - no-mask",
+      "request":{
+        "resource":{"elements":{"database":"hr2", "table":"employee2"}},
+        "accessType":"select","user":"user2","userGroups":[],"requestData":"select date_of_birth from hr2.employee2;' for user2"
+      },
+      "rowFilterResult":{"filterExpr":null,"policyId":-1}
+    }
+  ]
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/agents-common/src/test/resources/policyengine/test_policyengine_hive_masking.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_hive_masking.json b/agents-common/src/test/resources/policyengine/test_policyengine_hive_masking.json
deleted file mode 100644
index b0e4557..0000000
--- a/agents-common/src/test/resources/policyengine/test_policyengine_hive_masking.json
+++ /dev/null
@@ -1,156 +0,0 @@
-{
-  "serviceName":"hivedev",
-
-  "serviceDef":{
-    "name":"hive",
-    "id":3,
-    "resources":[
-      {"name":"database","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Database","description":"Hive Database"},
-      {"name":"table","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Table","description":"Hive Table"},
-      {"name":"udf","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive UDF","description":"Hive UDF"},
-      {"name":"column","level":3,"parent":"table","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Column","description":"Hive Column"}
-    ],
-    "accessTypes":[
-      {"name":"select","label":"Select"},
-      {"name":"update","label":"Update"},
-      {"name":"create","label":"Create"},
-      {"name":"drop","label":"Drop"},
-      {"name":"alter","label":"Alter"},
-      {"name":"index","label":"Index"},
-      {"name":"lock","label":"Lock"},
-      {"name":"all","label":"All",
-        "impliedGrants": [
-          "select",
-          "update",
-          "create",
-          "drop",
-          "alter",
-          "index",
-          "lock"
-        ]
-      }
-    ],
-    "dataMaskDef": {
-      "maskTypes": [
-        {
-          "itemId": 1,
-          "name": "MASK",
-          "label": "Mask",
-          "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'"
-        },
-        {
-          "itemId": 2,
-          "name": "SHUFFLE",
-          "label": "Shuffle",
-          "description": "Randomly shuffle the contents"
-        },
-        {
-          "itemId": 10,
-          "name": "NULL",
-          "label": "NULL",
-          "description": "Replace with NULL"
-        }
-
-      ],
-      "accessTypes":[
-        {"name":"select","label":"Select"}
-      ],
-      "resources":[
-        {"name":"database","matcherOptions":{"wildCard":false}},
-        {"name":"table","matcherOptions":{"wildCard":false}},
-        {"name":"column","matcherOptions":{"wildCard":false}}
-      ]
-    }
-  },
-
-  "policies":[
-    {"id":1,"name":"db=*: audit-all-access","isEnabled":true,"isAuditEnabled":true,
-     "resources":{"database":{"values":["*"]},"table":{"values":["*"]},"column":{"values":["*"]}},
-     "policyItems":[
-       {"accesses":[{"type":"all","isAllowed":true}],"users":["hive", "user1", "user2"],"groups":["public"],"delegateAdmin":false}
-     ]
-    },
-    {"id":101,"name":"db=*, table=*, column=ssn: mask ssn column in all tables, databases","isEnabled":true,"isAuditEnabled":true,"policyType":1,
-      "resources":{"database":{"values":["employee"]},"table":{"values":["personal"]},"column":{"values":["ssn"]}},
-      "dataMaskPolicyItems":[
-        {"accesses":[{"type":"select","isAllowed":true}],"users":["user1"],"groups":[],"delegateAdmin":false,
-         "dataMaskInfo": {"dataMaskType":"MASK"}
-        },
-        {"accesses":[{"type":"select","isAllowed":true}],"users":["user2"],"groups":[],"delegateAdmin":false,
-          "dataMaskInfo": {"dataMaskType":"SHUFFLE"}
-        }
-      ]
-    },
-    {"id":102,"name":"db=hr, table=*, column=date_of_birth: mask date_of_birth column in all tables in hr database","isEnabled":true,"isAuditEnabled":true,"policyType":1,
-      "resources":{"database":{"values":["hr"]},"table":{"values":["employee"]},"column":{"values":["date_of_birth"]}},
-      "dataMaskPolicyItems":[
-        {"accesses":[{"type":"select","isAllowed":true}],"users":["user1"],"groups":[],"delegateAdmin":false,
-          "dataMaskInfo": {"dataMaskType":"MASK"}
-        },
-        {"accesses":[{"type":"select","isAllowed":true}],"users":["user2"],"groups":[],"delegateAdmin":false,
-          "dataMaskInfo": {"dataMaskType":"SHUFFLE"}
-        }
-      ]
-    }
-  ],
-
-  "tests":[
-    {"name":"'select ssn from employee.personal;' for user1 - maskType=MASK",
-      "request":{
-        "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}},
-        "accessType":"select","user":"user1","userGroups":[],"requestData":"select ssn from employee.personal;' for user1"
-      },
-      "dataMaskResult":{"maskType":"MASK","maskCondition":null,"maskValue":null,"policyId":101}
-    },
-    {"name":"'select ssn from employee.personal;' for user2 - maskType=SHUFFLE",
-      "request":{
-        "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}},
-        "accessType":"select","user":"user2","userGroups":[],"requestData":"select ssn from employee.personal;' for user2"
-      },
-      "dataMaskResult":{"maskType":"SHUFFLE","maskCondition":null,"maskValue":null,"policyId":101}
-    },
-    {"name":"'select ssn from employee.personal;' for user3 - no-mask",
-      "request":{
-        "resource":{"elements":{"database":"employee", "table":"personal", "column":"ssn"}},
-        "accessType":"select","user":"user3","userGroups":[],"requestData":"select ssn from employee.personal;' for user3"
-      },
-      "dataMaskResult":{"maskType":null,"maskCondition":null,"maskValue":null,"policyId":-1}
-    },
-    {"name":"'select name from employee.personal;' for user1 - no-mask",
-      "request":{
-        "resource":{"elements":{"database":"employee", "table":"personal", "column":"name"}},
-        "accessType":"select","user":"user1","userGroups":[],"requestData":"select name from employee.personal;' for user1"
-      },
-      "dataMaskResult":{"maskType":null,"maskCondition":null,"maskValue":null,"policyId":-1}
-    },
-    {"name":"'select date_of_birth from hr.employee;' for user1 - maskType=MASK",
-      "request":{
-        "resource":{"elements":{"database":"hr", "table":"employee", "column":"date_of_birth"}},
-        "accessType":"select","user":"user1","userGroups":[],"requestData":"select date_of_birth from hr.employee;' for user1"
-      },
-      "dataMaskResult":{"maskType":"MASK","maskCondition":null,"maskValue":null,"policyId":102}
-    },
-    {"name":"'select date_of_birth from hr.employee;' for user2 - maskType=SHUFFLE",
-      "request":{
-        "resource":{"elements":{"database":"hr", "table":"employee", "column":"date_of_birth"}},
-        "accessType":"select","user":"user2","userGroups":[],"requestData":"select date_of_birth from hr.employee2;' for user2"
-      },
-      "dataMaskResult":{"maskType":"SHUFFLE","maskCondition":null,"maskValue":null,"policyId":102}
-    },
-    {"name":"'select date_of_birth1 from hr.employee;' for user1 - no-mask",
-      "request":{
-        "resource":{"elements":{"database":"hr", "table":"employee", "column":"date_of_birth1"}},
-        "accessType":"select","user":"user1","userGroups":[],"requestData":"select date_of_birth1 from hr.employee;' for user1"
-      },
-      "dataMaskResult":{"maskType":null,"maskCondition":null,"maskValue":null,"policyId":-1}
-    },
-    {"name":"'select date_of_birth from hr2.employee2;' for user2 - no-mask",
-      "request":{
-        "resource":{"elements":{"database":"hr2", "table":"employee2", "column":"date_of_birth"}},
-        "accessType":"select","user":"user2","userGroups":[],"requestData":"select date_of_birth from hr2.employee2;' for user2"
-      },
-      "dataMaskResult":{"maskType":null,"maskCondition":null,"maskValue":null,"policyId":-1}
-    }
-  ]
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
----------------------------------------------------------------------
diff --git a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
index e0e1e7a..a2a49ad 100644
--- a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
+++ b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
@@ -30,6 +30,7 @@ import org.apache.ranger.plugin.policyengine.RangerAccessResource;
 import org.apache.ranger.plugin.policyengine.RangerAccessResult;
 
 import com.google.common.collect.Lists;
+import org.apache.ranger.plugin.policyengine.RangerDataMaskResult;
 
 public class RangerHiveAuditHandler extends RangerDefaultAuditHandler {
 
@@ -59,14 +60,19 @@ public class RangerHiveAuditHandler extends RangerDefaultAuditHandler {
 		RangerAccessResource resource = request.getResource();
 
 		String accessType = null;
-		if(request instanceof RangerHiveAccessRequest) {
-			RangerHiveAccessRequest hiveRequest = (RangerHiveAccessRequest)request;
 
-			accessType = hiveRequest.getHiveAccessType().toString();
-		}
+		if(result instanceof RangerDataMaskResult) {
+			accessType = ((RangerDataMaskResult)result).getMaskType();
+		} else {
+			if (request instanceof RangerHiveAccessRequest) {
+				RangerHiveAccessRequest hiveRequest = (RangerHiveAccessRequest) request;
 
-		if(StringUtils.isEmpty(accessType)) {
-			accessType = request.getAccessType();
+				accessType = hiveRequest.getHiveAccessType().toString();
+			}
+
+			if (StringUtils.isEmpty(accessType)) {
+				accessType = request.getAccessType();
+			}
 		}
 
 		String resourcePath = resource != null ? resource.getAsString() : null;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/db/mysql/patches/020-datamask-policy.sql
----------------------------------------------------------------------
diff --git a/security-admin/db/mysql/patches/020-datamask-policy.sql b/security-admin/db/mysql/patches/020-datamask-policy.sql
index 8a612b3..fffa613 100644
--- a/security-admin/db/mysql/patches/020-datamask-policy.sql
+++ b/security-admin/db/mysql/patches/020-datamask-policy.sql
@@ -22,6 +22,9 @@ delimiter ;;
 	if not exists (select * from information_schema.columns where table_schema=database() and table_name = 'x_access_type_def' and column_name = 'datamask_options') then
 		ALTER TABLE `x_access_type_def` ADD `datamask_options` varchar(1024) DEFAULT NULL;
  	end if;
+	if not exists (select * from information_schema.columns where table_schema=database() and table_name = 'x_access_type_def' and column_name = 'rowfilter_options') then
+		ALTER TABLE `x_access_type_def` ADD `rowfilter_options` varchar(1024) DEFAULT NULL;
+ 	end if;
  end if; 
 end;;
 
@@ -38,6 +41,9 @@ delimiter ;;
 	if not exists (select * from information_schema.columns where table_schema=database() and table_name = 'x_resource_def' and column_name = 'datamask_options') then
 		ALTER TABLE `x_resource_def` ADD `datamask_options` varchar(1024) DEFAULT NULL;
  	end if;
+	if not exists (select * from information_schema.columns where table_schema=database() and table_name = 'x_resource_def' and column_name = 'rowfilter_options') then
+		ALTER TABLE `x_resource_def` ADD `rowfilter_options` varchar(1024) DEFAULT NULL;
+ 	end if;
  end if; 
 end;;
 
@@ -93,3 +99,20 @@ CONSTRAINT `x_policy_item_datamask_FK_added_by_id` FOREIGN KEY (`added_by_id`) R
 CONSTRAINT `x_policy_item_datamask_FK_upd_by_id` FOREIGN KEY (`upd_by_id`) REFERENCES `x_portal_user` (`id`)
 );
 CREATE INDEX x_policy_item_datamask_IDX_policy_item_id ON x_policy_item_datamask(policy_item_id);
+
+DROP TABLE IF EXISTS `x_policy_item_rowfilter`;
+CREATE TABLE `x_policy_item_rowfilter` (
+`id` bigint(20) NOT NULL AUTO_INCREMENT ,
+`guid` varchar(1024) DEFAULT NULL,
+`create_time` datetime DEFAULT NULL,
+`update_time` datetime DEFAULT NULL,
+`added_by_id` bigint(20) DEFAULT NULL,
+`upd_by_id` bigint(20) DEFAULT NULL,
+`policy_item_id` bigint(20) NOT NULL, 
+`filter_expr` varchar(1024) DEFAULT NULL,
+primary key (id), 
+CONSTRAINT `x_policy_item_rowfilter_FK_policy_item_id` FOREIGN KEY (`policy_item_id`) REFERENCES `x_policy_item` (`id`) ,
+CONSTRAINT `x_policy_item_rowfilter_FK_added_by_id` FOREIGN KEY (`added_by_id`) REFERENCES `x_portal_user` (`id`),
+CONSTRAINT `x_policy_item_rowfilter_FK_upd_by_id` FOREIGN KEY (`upd_by_id`) REFERENCES `x_portal_user` (`id`)
+);
+CREATE INDEX x_policy_item_rowfilter_IDX_policy_item_id ON x_policy_item_rowfilter(policy_item_id);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/db/postgres/patches/020-datamask-policy.sql
----------------------------------------------------------------------
diff --git a/security-admin/db/postgres/patches/020-datamask-policy.sql b/security-admin/db/postgres/patches/020-datamask-policy.sql
index d000822..393684b 100644
--- a/security-admin/db/postgres/patches/020-datamask-policy.sql
+++ b/security-admin/db/postgres/patches/020-datamask-policy.sql
@@ -20,11 +20,16 @@ CREATE OR REPLACE FUNCTION add_datamask_options_to_x_access_type_def_table()
 RETURNS void AS $$
 DECLARE
  exists_access_type_def_datamask_options integer := 0;
+ exists_access_type_def_rowfilter_options integer := 0;
 BEGIN
  select count(*) into exists_access_type_def_datamask_options from pg_attribute where attrelid in(select oid from pg_class where relname='x_access_type_def') and attname='datamask_options';
+ select count(*) into exists_access_type_def_rowfilter_options from pg_attribute where attrelid in(select oid from pg_class where relname='x_access_type_def') and attname='rowfilter_options';
  IF exists_access_type_def_datamask_options = 0 THEN
  	ALTER TABLE x_access_type_def ADD COLUMN datamask_options VARCHAR(1024) DEFAULT NULL;
  END IF;
+ IF exists_access_type_def_rowfilter_options = 0 THEN
+ 	ALTER TABLE x_access_type_def ADD COLUMN rowfilter_options VARCHAR(1024) DEFAULT NULL;
+ END IF;
 END;
 $$ LANGUAGE plpgsql;
 
@@ -33,11 +38,16 @@ CREATE OR REPLACE FUNCTION add_datamask_options_to_x_resource_def_table()
 RETURNS void AS $$
 DECLARE
  exists_resource_def_datamask_options integer := 0;
+ exists_resource_def_rowfilter_options integer := 0;
 BEGIN
  select count(*) into exists_resource_def_datamask_options from pg_attribute where attrelid in(select oid from pg_class where relname='x_resource_def') and attname='datamask_options';
+ select count(*) into exists_resource_def_rowfilter_options from pg_attribute where attrelid in(select oid from pg_class where relname='x_resource_def') and attname='rowfilter_options';
  IF exists_resource_def_datamask_options = 0 THEN
  	ALTER TABLE x_resource_def ADD COLUMN datamask_options VARCHAR(1024) DEFAULT NULL;
  END IF;
+ IF exists_resource_def_rowfilter_options = 0 THEN
+ 	ALTER TABLE x_resource_def ADD COLUMN rowfilter_options VARCHAR(1024) DEFAULT NULL;
+ END IF;
 END;
 $$ LANGUAGE plpgsql;
 
@@ -96,3 +106,23 @@ CREATE TABLE x_policy_item_datamask (
   CONSTRAINT x_policy_item_datamask_FK_upd_by_id FOREIGN KEY (upd_by_id) REFERENCES x_portal_user (id)
 );
 CREATE INDEX x_policy_item_datamask_IDX_policy_item_id ON x_policy_item_datamask(policy_item_id);
+
+DROP TABLE IF EXISTS x_policy_item_rowfilter;
+DROP SEQUENCE IF EXISTS x_policy_item_rowfilter_seq;
+
+CREATE SEQUENCE x_policy_item_rowfilter_seq;
+CREATE TABLE x_policy_item_rowfilter (
+  id BIGINT DEFAULT nextval('x_policy_item_rowfilter_seq'::regclass),
+  guid VARCHAR(1024) DEFAULT NULL,
+  create_time TIMESTAMP DEFAULT NULL,
+  update_time TIMESTAMP DEFAULT NULL,
+  added_by_id BIGINT DEFAULT NULL,
+  upd_by_id BIGINT DEFAULT NULL,
+  policy_item_id BIGINT NOT NULL, 
+  filter_expr VARCHAR(1024) DEFAULT NULL,
+  primary key (id), 
+  CONSTRAINT x_policy_item_rowfilter_FK_policy_item_id FOREIGN KEY (policy_item_id) REFERENCES x_policy_item (id) ,
+  CONSTRAINT x_policy_item_rowfilter_FK_added_by_id FOREIGN KEY (added_by_id) REFERENCES x_portal_user (id),
+  CONSTRAINT x_policy_item_rowfilter_FK_upd_by_id FOREIGN KEY (upd_by_id) REFERENCES x_portal_user (id)
+);
+CREATE INDEX x_policy_item_rowfilter_IDX_policy_item_id ON x_policy_item_rowfilter(policy_item_id);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyRetriever.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyRetriever.java b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyRetriever.java
index 89daaea..469ebbe 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyRetriever.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyRetriever.java
@@ -37,7 +37,9 @@ import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemRowFilterInfo;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem;
 import org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
 
@@ -408,7 +410,8 @@ public class RangerPolicyRetriever {
 		final ListIterator<XXPolicyItemGroupPerm> iterGroupPerms;
 		final ListIterator<XXPolicyItemAccess>    iterAccesses;
 		final ListIterator<XXPolicyItemCondition> iterConditions;
-		final ListIterator<XXPolicyItemDataMaskInfo> iterDataMaskInfos;
+		final ListIterator<XXPolicyItemDataMaskInfo>  iterDataMaskInfos;
+		final ListIterator<XXPolicyItemRowFilterInfo> iterRowFilterInfos;
 
 		RetrieverContext(XXService xService) {
 			Long serviceId = xService == null ? null : xService.getId();
@@ -421,7 +424,8 @@ public class RangerPolicyRetriever {
 			List<XXPolicyItemGroupPerm> xGroupPerms   = daoMgr.getXXPolicyItemGroupPerm().findByServiceId(serviceId);
 			List<XXPolicyItemAccess>    xAccesses     = daoMgr.getXXPolicyItemAccess().findByServiceId(serviceId);
 			List<XXPolicyItemCondition> xConditions   = daoMgr.getXXPolicyItemCondition().findByServiceId(serviceId);
-			List<XXPolicyItemDataMaskInfo> xDataMaskInfos = daoMgr.getXXPolicyItemDataMaskInfo().findByServiceId(serviceId);
+			List<XXPolicyItemDataMaskInfo>  xDataMaskInfos  = daoMgr.getXXPolicyItemDataMaskInfo().findByServiceId(serviceId);
+			List<XXPolicyItemRowFilterInfo> xRowFilterInfos = daoMgr.getXXPolicyItemRowFilterInfo().findByServiceId(serviceId);
 
 			this.service          = xService;
 			this.iterPolicy       = xPolicies.listIterator();
@@ -432,7 +436,8 @@ public class RangerPolicyRetriever {
 			this.iterGroupPerms   = xGroupPerms.listIterator();
 			this.iterAccesses     = xAccesses.listIterator();
 			this.iterConditions   = xConditions.listIterator();
-			this.iterDataMaskInfos = xDataMaskInfos.listIterator();
+			this.iterDataMaskInfos  = xDataMaskInfos.listIterator();
+			this.iterRowFilterInfos = xRowFilterInfos.listIterator();
 		}
 
 		RetrieverContext(XXPolicy xPolicy) {
@@ -450,7 +455,8 @@ public class RangerPolicyRetriever {
 			List<XXPolicyItemGroupPerm> xGroupPerms   = daoMgr.getXXPolicyItemGroupPerm().findByPolicyId(policyId);
 			List<XXPolicyItemAccess>    xAccesses     = daoMgr.getXXPolicyItemAccess().findByPolicyId(policyId);
 			List<XXPolicyItemCondition> xConditions   = daoMgr.getXXPolicyItemCondition().findByPolicyId(policyId);
-			List<XXPolicyItemDataMaskInfo> xDataMaskInfos = daoMgr.getXXPolicyItemDataMaskInfo().findByPolicyId(policyId);
+			List<XXPolicyItemDataMaskInfo>  xDataMaskInfos  = daoMgr.getXXPolicyItemDataMaskInfo().findByPolicyId(policyId);
+			List<XXPolicyItemRowFilterInfo> xRowFilterInfos = daoMgr.getXXPolicyItemRowFilterInfo().findByPolicyId(policyId);
 
 			this.service          = xService;
 			this.iterPolicy       = xPolicies.listIterator();
@@ -461,7 +467,8 @@ public class RangerPolicyRetriever {
 			this.iterGroupPerms   = xGroupPerms.listIterator();
 			this.iterAccesses     = xAccesses.listIterator();
 			this.iterConditions   = xConditions.listIterator();
-			this.iterDataMaskInfos = xDataMaskInfos.listIterator();
+			this.iterDataMaskInfos  = xDataMaskInfos.listIterator();
+			this.iterRowFilterInfos = xRowFilterInfos.listIterator();
 		}
 
 		RangerPolicy getNextPolicy() {
@@ -549,7 +556,8 @@ public class RangerPolicyRetriever {
 									|| iterGroupPerms.hasNext()
 									|| iterAccesses.hasNext()
 									|| iterConditions.hasNext()
-									|| iterDataMaskInfos.hasNext();
+									|| iterDataMaskInfos.hasNext()
+									|| iterRowFilterInfos.hasNext();
 
 			return !moreToProcess;
 		}
@@ -592,15 +600,22 @@ public class RangerPolicyRetriever {
 				XXPolicyItem xPolicyItem = iterPolicyItems.next();
 
 				if(xPolicyItem.getPolicyid().equals(policy.getId())) {
-					final RangerPolicyItem         policyItem;
-					final RangerDataMaskPolicyItem dataMaskPolicyItem;
-
-					if(xPolicyItem.getItemType() == RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATA_MASKING) {
-						dataMaskPolicyItem = new RangerDataMaskPolicyItem();
-						policyItem         = dataMaskPolicyItem;
+					final RangerPolicyItem          policyItem;
+					final RangerDataMaskPolicyItem  dataMaskPolicyItem;
+					final RangerRowFilterPolicyItem rowFilterPolicyItem;
+
+					if(xPolicyItem.getItemType() == RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATAMASK) {
+						dataMaskPolicyItem  = new RangerDataMaskPolicyItem();
+						rowFilterPolicyItem = null;
+						policyItem          = dataMaskPolicyItem;
+					} else if(xPolicyItem.getItemType() == RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ROWFILTER) {
+						dataMaskPolicyItem  = null;
+						rowFilterPolicyItem = new RangerRowFilterPolicyItem();
+						policyItem          = rowFilterPolicyItem;
 					} else {
-						dataMaskPolicyItem = null;
-						policyItem         = new RangerPolicyItem();
+						dataMaskPolicyItem  = null;
+						rowFilterPolicyItem = null;
+						policyItem          = new RangerPolicyItem();
 					}
 
 
@@ -674,7 +689,7 @@ public class RangerPolicyRetriever {
 						while (iterDataMaskInfos.hasNext()) {
 							XXPolicyItemDataMaskInfo xDataMaskInfo = iterDataMaskInfos.next();
 
-							if (xDataMaskInfo.getPolicyitemid().equals(xPolicyItem.getId())) {
+							if (xDataMaskInfo.getPolicyItemId().equals(xPolicyItem.getId())) {
 								dataMaskPolicyItem.setDataMaskInfo(new RangerPolicyItemDataMaskInfo(lookupCache.getDataMaskName(xDataMaskInfo.getType()), xDataMaskInfo.getConditionExpr(), xDataMaskInfo.getValueExpr()));
 							} else {
 								if (iterDataMaskInfos.hasPrevious()) {
@@ -685,6 +700,21 @@ public class RangerPolicyRetriever {
 						}
 					}
 
+					if(rowFilterPolicyItem != null) {
+						while (iterRowFilterInfos.hasNext()) {
+							XXPolicyItemRowFilterInfo xRowFilterInfo = iterRowFilterInfos.next();
+
+							if (xRowFilterInfo.getPolicyItemId().equals(xPolicyItem.getId())) {
+								rowFilterPolicyItem.setRowFilterInfo(new RangerPolicyItemRowFilterInfo(xRowFilterInfo.getFilterExpr()));
+							} else {
+								if (iterRowFilterInfos.hasPrevious()) {
+									iterRowFilterInfos.previous();
+								}
+								break;
+							}
+						}
+					}
+
 
 					int itemType = xPolicyItem.getItemType() == null ? RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW : xPolicyItem.getItemType();
 
@@ -696,10 +726,12 @@ public class RangerPolicyRetriever {
 						policy.getAllowExceptions().add(policyItem);
 					} else if(itemType == RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS) {
 						policy.getDenyExceptions().add(policyItem);
-					} else if(itemType == RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATA_MASKING) {
+					} else if(itemType == RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATAMASK) {
 						policy.getDataMaskPolicyItems().add(dataMaskPolicyItem);
-					} else { // unknown itemType.. set to default type
-						policy.getPolicyItems().add(policyItem);
+					} else if(itemType == RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ROWFILTER) {
+						policy.getRowFilterPolicyItems().add(rowFilterPolicyItem);
+					} else { // unknown itemType
+						LOG.warn("RangerPolicyRetriever.getPolicy(policyId=" + policy.getId() + "): ignoring unknown policyItemType " + itemType);
 					}
 				} else if(xPolicyItem.getPolicyid().compareTo(policy.getId()) > 0) {
 					if(iterPolicyItems.hasPrevious()) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index c4a823c..a8f063b 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -34,9 +34,12 @@ import org.apache.ranger.db.*;
 import org.apache.ranger.entity.*;
 import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemCondition;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemRowFilterInfo;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 import org.apache.ranger.plugin.model.RangerPolicyResourceSignature;
 import org.apache.ranger.plugin.model.RangerService;
@@ -49,6 +52,7 @@ import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerEnumElementDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerPolicyConditionDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerRowFilterDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerServiceConfigDef;
 import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
 import org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator;
@@ -212,9 +216,14 @@ public class ServiceDBStore extends AbstractServiceStore {
 		List<RangerPolicyConditionDef> policyConditions = serviceDef.getPolicyConditions();
 		List<RangerContextEnricherDef> contextEnrichers = serviceDef.getContextEnrichers();
 		List<RangerEnumDef> enums = serviceDef.getEnums();
-		RangerDataMaskDef dataMaskDef = serviceDef.getDataMaskDef();
+		RangerDataMaskDef           dataMaskDef          = serviceDef.getDataMaskDef();
+		RangerRowFilterDef          rowFilterDef         = serviceDef.getRowFilterDef();
+		List<RangerDataMaskTypeDef> dataMaskTypes        = dataMaskDef == null || dataMaskDef.getMaskTypes() == null ? new ArrayList<RangerDataMaskTypeDef>() : dataMaskDef.getMaskTypes();
+		List<RangerAccessTypeDef>   dataMaskAccessTypes  = dataMaskDef == null || dataMaskDef.getAccessTypes() == null ? new ArrayList<RangerAccessTypeDef>() : dataMaskDef.getAccessTypes();
+		List<RangerResourceDef>     dataMaskResources    = dataMaskDef == null || dataMaskDef.getResources() == null ? new ArrayList<RangerResourceDef>() : dataMaskDef.getResources();
+		List<RangerAccessTypeDef>   rowFilterAccessTypes = rowFilterDef == null || rowFilterDef.getAccessTypes() == null ? new ArrayList<RangerAccessTypeDef>() : rowFilterDef.getAccessTypes();
+		List<RangerResourceDef>     rowFilterResources   = rowFilterDef == null || rowFilterDef.getResources() == null ? new ArrayList<RangerResourceDef>() : rowFilterDef.getResources();
 
-		
 		// While creating, value of version should be 1.
 		serviceDef.setVersion(Long.valueOf(1));
 		
@@ -325,93 +334,100 @@ public class ServiceDBStore extends AbstractServiceStore {
 			}
 		}
 
-		if(dataMaskDef != null) {
-			List<RangerDataMaskTypeDef> dataMaskTypes       = dataMaskDef.getMaskTypes();
-			List<RangerAccessTypeDef>   dataMaskAccessTypes = dataMaskDef.getAccessTypes();
-			List<RangerResourceDef>     dataMaskResources   = dataMaskDef.getResources();
+		XXDataMaskTypeDefDao xxDataMaskDefDao = daoMgr.getXXDataMaskTypeDef();
+		for (int i = 0; i < dataMaskTypes.size(); i++) {
+			RangerDataMaskTypeDef dataMask = dataMaskTypes.get(i);
 
-			if(CollectionUtils.isNotEmpty(dataMaskTypes)) {
-				XXDataMaskTypeDefDao xxDataMaskDefDao = daoMgr.getXXDataMaskTypeDef();
-				for (int i = 0; i < dataMaskTypes.size(); i++) {
-					RangerDataMaskTypeDef dataMask = dataMaskTypes.get(i);
+			XXDataMaskTypeDef xDataMaskDef = new XXDataMaskTypeDef();
+			xDataMaskDef = serviceDefService.populateRangerDataMaskDefToXX(dataMask, xDataMaskDef, createdSvcDef,
+					RangerServiceDefService.OPERATION_CREATE_CONTEXT);
+			xDataMaskDef.setOrder(i);
+			xDataMaskDef = xxDataMaskDefDao.create(xDataMaskDef);
+		}
 
-					XXDataMaskTypeDef xDataMaskDef = new XXDataMaskTypeDef();
-					xDataMaskDef = serviceDefService.populateRangerDataMaskDefToXX(dataMask, xDataMaskDef, createdSvcDef,
-							RangerServiceDefService.OPERATION_CREATE_CONTEXT);
-					xDataMaskDef.setOrder(i);
-					xDataMaskDef = xxDataMaskDefDao.create(xDataMaskDef);
-				}
+		List<XXAccessTypeDef> xxAccessTypeDefs = xxATDDao.findByServiceDefId(createdSvcDef.getId());
+
+		for(RangerAccessTypeDef accessType : dataMaskAccessTypes) {
+			if(! isAccessTypeInList(accessType.getName(), xxAccessTypeDefs)) {
+				throw restErrorUtil.createRESTException("accessType with name: "
+								+ accessType.getName() + " does not exists", MessageEnums.DATA_NOT_FOUND);
 			}
+		}
 
-			if(CollectionUtils.isNotEmpty(dataMaskAccessTypes)) {
-				List<XXAccessTypeDef> xxAccessTypeDefs = xxATDDao.findByServiceDefId(xServiceDef.getId());
+		for(RangerAccessTypeDef accessType : rowFilterAccessTypes) {
+			if(! isAccessTypeInList(accessType.getName(), xxAccessTypeDefs)) {
+				throw restErrorUtil.createRESTException("accessType with name: "
+						+ accessType.getName() + " does not exists", MessageEnums.DATA_NOT_FOUND);
+			}
+		}
 
-				for(RangerAccessTypeDef accessType : dataMaskAccessTypes) {
-					boolean found = false;
-					for(XXAccessTypeDef xxAccessTypeDef : xxAccessTypeDefs) {
-						if(StringUtils.equals(xxAccessTypeDef.getName(), accessType.getName())) {
-							found = true;
+		for(XXAccessTypeDef xxAccessTypeDef : xxAccessTypeDefs) {
+			String dataMaskOptions  = null;
+			String rowFilterOptions = null;
 
-							break;
-						}
-					}
+			for(RangerAccessTypeDef accessTypeDef : dataMaskAccessTypes) {
+				if(StringUtils.equals(accessTypeDef.getName(), xxAccessTypeDef.getName())) {
+					dataMaskOptions = svcDefServiceWithAssignedId.objectToJson(accessTypeDef);
+					break;
+				}
+			}
 
-					if(! found) {
-						throw restErrorUtil.createRESTException("accessType with name: "
-										+ accessType + " does not exists", MessageEnums.DATA_NOT_FOUND);
-					}
+			for(RangerAccessTypeDef accessTypeDef : rowFilterAccessTypes) {
+				if(StringUtils.equals(accessTypeDef.getName(), xxAccessTypeDef.getName())) {
+					rowFilterOptions = svcDefServiceWithAssignedId.objectToJson(accessTypeDef);
+					break;
 				}
+			}
 
-				for(XXAccessTypeDef xxAccessTypeDef : xxAccessTypeDefs) {
-					String dataMaskOptions = null;
+			if(!StringUtils.equals(dataMaskOptions, xxAccessTypeDef.getDataMaskOptions()) ||
+			   !StringUtils.equals(rowFilterOptions, xxAccessTypeDef.getRowFilterOptions())) {
+				xxAccessTypeDef.setDataMaskOptions(dataMaskOptions);
+				xxAccessTypeDef.setRowFilterOptions(rowFilterOptions);
 
-					for(RangerAccessTypeDef dataMaskAccessType : dataMaskAccessTypes) {
-						if(StringUtils.equals(dataMaskAccessType.getName(), xxAccessTypeDef.getName())) {
-							dataMaskOptions = svcDefServiceWithAssignedId.objectToJson(dataMaskAccessType);
-							break;
-						}
-					}
+				xxATDDao.update(xxAccessTypeDef);
+			}
+		}
 
-					if(! StringUtils.equals(dataMaskOptions, xxAccessTypeDef.getDataMaskOptions())) {
-						xxAccessTypeDef.setDataMaskOptions(dataMaskOptions);
-						xxATDDao.update(xxAccessTypeDef);
-					}
-				}
+		List<XXResourceDef> xxResourceDefs = xxResDefDao.findByServiceDefId(createdSvcDef.getId());
+
+		for(RangerResourceDef resource : dataMaskResources) {
+			if(! isResourceInList(resource.getName(), xxResourceDefs)) {
+				throw restErrorUtil.createRESTException("resource with name: "
+						+ resource.getName() + " does not exists", MessageEnums.DATA_NOT_FOUND);
 			}
+		}
 
-			if(CollectionUtils.isNotEmpty(dataMaskResources)) {
-				List<XXResourceDef> xxResourceDefs = xxResDefDao.findByServiceDefId(xServiceDef.getId());
+		for(RangerResourceDef resource : rowFilterResources) {
+			if(! isResourceInList(resource.getName(), xxResourceDefs)) {
+				throw restErrorUtil.createRESTException("resource with name: "
+						+ resource.getName() + " does not exists", MessageEnums.DATA_NOT_FOUND);
+			}
+		}
 
-				for(RangerResourceDef resource : dataMaskResources) {
-					boolean found = false;
-					for(XXResourceDef xxResourceDef : xxResourceDefs) {
-						if(StringUtils.equals(xxResourceDef.getName(), resource.getName())) {
-							found = true;
-							break;
-						}
-					}
+		for(XXResourceDef xxResourceDef : xxResourceDefs) {
+			String dataMaskOptions  = null;
+			String rowFilterOptions = null;
 
-					if(! found) {
-						throw restErrorUtil.createRESTException("resource with name: "
-								+ resource + " does not exists", MessageEnums.DATA_NOT_FOUND);
-					}
+			for(RangerResourceDef resource : dataMaskResources) {
+				if(StringUtils.equals(resource.getName(), xxResourceDef.getName())) {
+					dataMaskOptions = svcDefServiceWithAssignedId.objectToJson(resource);
+					break;
 				}
+			}
 
-				for(XXResourceDef xxResourceDef : xxResourceDefs) {
-					String dataMaskOptions = null;
+			for(RangerResourceDef resource : rowFilterResources) {
+				if(StringUtils.equals(resource.getName(), xxResourceDef.getName())) {
+					rowFilterOptions = svcDefServiceWithAssignedId.objectToJson(resource);
+					break;
+				}
+			}
 
-					for(RangerResourceDef dataMaskResource : dataMaskResources) {
-						if(StringUtils.equals(dataMaskResource.getName(), xxResourceDef.getName())) {
-							dataMaskOptions = svcDefServiceWithAssignedId.objectToJson(dataMaskResource);
-							break;
-						}
-					}
+			if(!StringUtils.equals(dataMaskOptions, xxResourceDef.getDataMaskOptions()) ||
+			   !StringUtils.equals(rowFilterOptions, xxResourceDef.getRowFilterOptions())) {
+				xxResourceDef.setDataMaskOptions(dataMaskOptions);
+				xxResourceDef.setRowFilterOptions(rowFilterOptions);
 
-					if(! StringUtils.equals(dataMaskOptions, xxResourceDef.getDataMaskOptions())) {
-						xxResourceDef.setDataMaskOptions(dataMaskOptions);
-						xxResDefDao.update(xxResourceDef);
-					}
-				}
+				xxResDefDao.update(xxResourceDef);
 			}
 		}
 
@@ -462,6 +478,7 @@ public class ServiceDBStore extends AbstractServiceStore {
 		List<RangerContextEnricherDef> contextEnrichers = serviceDef.getContextEnrichers() != null 	? serviceDef.getContextEnrichers() 	  : new ArrayList<RangerContextEnricherDef>();
 		List<RangerEnumDef> enums 						= serviceDef.getEnums() != null 			? serviceDef.getEnums() 			  : new ArrayList<RangerEnumDef>();
 		RangerDataMaskDef dataMaskDef                   = serviceDef.getDataMaskDef();
+		RangerRowFilterDef rowFilterDef                 = serviceDef.getRowFilterDef();
 
 		serviceDef.setCreateTime(existing.getCreateTime());
 		serviceDef.setGuid(existing.getGuid());
@@ -470,7 +487,7 @@ public class ServiceDBStore extends AbstractServiceStore {
 		serviceDef = serviceDefService.update(serviceDef);
 		XXServiceDef createdSvcDef = daoMgr.getXXServiceDef().getById(serviceDefId);
 
-		updateChildObjectsOfServiceDef(createdSvcDef, configs, resources, accessTypes, policyConditions, contextEnrichers, enums, dataMaskDef);
+		updateChildObjectsOfServiceDef(createdSvcDef, configs, resources, accessTypes, policyConditions, contextEnrichers, enums, dataMaskDef, rowFilterDef);
 
 		RangerServiceDef updatedSvcDef = getServiceDef(serviceDefId);
 		dataHistService.createObjectDataHistory(updatedSvcDef, RangerDataHistService.ACTION_UPDATE);
@@ -488,7 +505,7 @@ public class ServiceDBStore extends AbstractServiceStore {
 	private void updateChildObjectsOfServiceDef(XXServiceDef createdSvcDef, List<RangerServiceConfigDef> configs,
 			List<RangerResourceDef> resources, List<RangerAccessTypeDef> accessTypes,
 			List<RangerPolicyConditionDef> policyConditions, List<RangerContextEnricherDef> contextEnrichers,
-			List<RangerEnumDef> enums, RangerServiceDef.RangerDataMaskDef dataMaskDef) {
+			List<RangerEnumDef> enums, RangerDataMaskDef dataMaskDef, RangerRowFilterDef rowFilterDef) {
 
 		Long serviceDefId = createdSvcDef.getId();
 
@@ -822,13 +839,18 @@ public class ServiceDBStore extends AbstractServiceStore {
 			}
 		}
 
-		List<RangerDataMaskTypeDef> dataMasks           = dataMaskDef == null || dataMaskDef.getMaskTypes() == null ? new ArrayList<RangerDataMaskTypeDef>() : dataMaskDef.getMaskTypes();
-		List<RangerAccessTypeDef>   dataMaskAccessTypes = dataMaskDef == null || dataMaskDef.getAccessTypes() == null ? new ArrayList<RangerAccessTypeDef>() : dataMaskDef.getAccessTypes();
-		List<RangerResourceDef>     dataMaskResources   = dataMaskDef == null || dataMaskDef.getResources() == null ? new ArrayList<RangerResourceDef>() : dataMaskDef.getResources();
-		XXDataMaskTypeDefDao        dataMaskTypeDao     = daoMgr.getXXDataMaskTypeDef();
-		List<XXDataMaskTypeDef>     xxDataMaskTypes     = dataMaskTypeDao.findByServiceDefId(serviceDefId);
+		List<RangerDataMaskTypeDef> dataMasks            = dataMaskDef == null || dataMaskDef.getMaskTypes() == null ? new ArrayList<RangerDataMaskTypeDef>() : dataMaskDef.getMaskTypes();
+		List<RangerAccessTypeDef>   dataMaskAccessTypes  = dataMaskDef == null || dataMaskDef.getAccessTypes() == null ? new ArrayList<RangerAccessTypeDef>() : dataMaskDef.getAccessTypes();
+		List<RangerResourceDef>     dataMaskResources    = dataMaskDef == null || dataMaskDef.getResources() == null ? new ArrayList<RangerResourceDef>() : dataMaskDef.getResources();
+		List<RangerAccessTypeDef>   rowFilterAccessTypes = rowFilterDef == null || rowFilterDef.getAccessTypes() == null ? new ArrayList<RangerAccessTypeDef>() : rowFilterDef.getAccessTypes();
+		List<RangerResourceDef>     rowFilterResources   = rowFilterDef == null || rowFilterDef.getResources() == null ? new ArrayList<RangerResourceDef>() : rowFilterDef.getResources();
+		XXDataMaskTypeDefDao        dataMaskTypeDao      = daoMgr.getXXDataMaskTypeDef();
+		List<XXDataMaskTypeDef>     xxDataMaskTypes      = dataMaskTypeDao.findByServiceDefId(serviceDefId);
+		List<XXAccessTypeDef>       xxAccessTypeDefs     = xxATDDao.findByServiceDefId(serviceDefId);
+		List<XXResourceDef>         xxResourceDefs       = xxResDefDao.findByServiceDefId(serviceDefId);
+
 		// create or update dataMasks
-		for (RangerServiceDef.RangerDataMaskTypeDef dataMask : dataMasks) {
+		for (RangerDataMaskTypeDef dataMask : dataMasks) {
 			boolean found = false;
 			for (XXDataMaskTypeDef xxDataMask : xxDataMaskTypes) {
 				if (xxDataMask.getItemId() != null && xxDataMask.getItemId().equals(dataMask.getItemId())) {
@@ -874,68 +896,82 @@ public class ServiceDBStore extends AbstractServiceStore {
 			}
 		}
 
-		List<XXAccessTypeDef> xxAccessTypeDefs = xxATDDao.findByServiceDefId(serviceDefId);
-
 		for(RangerAccessTypeDef accessType : dataMaskAccessTypes) {
-			boolean found = false;
-			for(XXAccessTypeDef xxAccessTypeDef : xxAccessTypeDefs) {
-				if(StringUtils.equals(xxAccessTypeDef.getName(), accessType.getName())) {
-					found = true;
-					break;
-				}
+			if(! isAccessTypeInList(accessType.getName(), xxAccessTypeDefs)) {
+				throw restErrorUtil.createRESTException("accessType with name: "
+						+ accessType.getName() + " does not exists", MessageEnums.DATA_NOT_FOUND);
 			}
+		}
 
-			if(! found) {
+		for(RangerAccessTypeDef accessType : rowFilterAccessTypes) {
+			if(! isAccessTypeInList(accessType.getName(), xxAccessTypeDefs)) {
 				throw restErrorUtil.createRESTException("accessType with name: "
-						+ accessType + " does not exists", MessageEnums.DATA_NOT_FOUND);
+						+ accessType.getName() + " does not exists", MessageEnums.DATA_NOT_FOUND);
 			}
 		}
 
 		for(XXAccessTypeDef xxAccessTypeDef : xxAccessTypeDefs) {
 			String dataMaskOptions = null;
+			String rowFilterOptions = null;
+
+			for(RangerAccessTypeDef accessTypeDef : dataMaskAccessTypes) {
+				if(StringUtils.equals(accessTypeDef.getName(), xxAccessTypeDef.getName())) {
+					dataMaskOptions = svcDefServiceWithAssignedId.objectToJson(accessTypeDef);
+					break;
+				}
+			}
 
-			for(RangerAccessTypeDef dataMaskAccessType : dataMaskAccessTypes) {
-				if(StringUtils.equals(dataMaskAccessType.getName(), xxAccessTypeDef.getName())) {
-					dataMaskOptions = svcDefServiceWithAssignedId.objectToJson(dataMaskAccessType);
+			for(RangerAccessTypeDef accessTypeDef : rowFilterAccessTypes) {
+				if(StringUtils.equals(accessTypeDef.getName(), xxAccessTypeDef.getName())) {
+					rowFilterOptions = svcDefServiceWithAssignedId.objectToJson(accessTypeDef);
 					break;
 				}
 			}
 
-			if(! StringUtils.equals(dataMaskOptions, xxAccessTypeDef.getDataMaskOptions())) {
+			if(!StringUtils.equals(dataMaskOptions, xxAccessTypeDef.getDataMaskOptions()) ||
+			   !StringUtils.equals(rowFilterOptions, xxAccessTypeDef.getRowFilterOptions())) {
 				xxAccessTypeDef.setDataMaskOptions(dataMaskOptions);
+				xxAccessTypeDef.setRowFilterOptions(rowFilterOptions);
 				xxATDDao.update(xxAccessTypeDef);
 			}
 		}
 
-		List<XXResourceDef> xxResourceDefs = xxResDefDao.findByServiceDefId(serviceDefId);
-
 		for(RangerResourceDef resource : dataMaskResources) {
-			boolean found = false;
-			for(XXResourceDef xxResourceDef : xxResourceDefs) {
-				if(StringUtils.equals(xxResourceDef.getName(), resource.getName())) {
-					found = true;
-					break;
-				}
+			if(! isResourceInList(resource.getName(), xxResourceDefs)) {
+				throw restErrorUtil.createRESTException("resource with name: "
+						+ resource.getName() + " does not exists", MessageEnums.DATA_NOT_FOUND);
 			}
+		}
 
-			if(! found) {
+		for(RangerResourceDef resource : rowFilterResources) {
+			if(! isResourceInList(resource.getName(), xxResourceDefs)) {
 				throw restErrorUtil.createRESTException("resource with name: "
-						+ resource + " does not exists", MessageEnums.DATA_NOT_FOUND);
+						+ resource.getName() + " does not exists", MessageEnums.DATA_NOT_FOUND);
 			}
 		}
 
 		for(XXResourceDef xxResourceDef : xxResourceDefs) {
-			String dataMaskOptions = null;
+			String dataMaskOptions  = null;
+			String rowFilterOptions = null;
 
-			for(RangerResourceDef dataMaskResource : dataMaskResources) {
-				if(StringUtils.equals(dataMaskResource.getName(), xxResourceDef.getName())) {
-					dataMaskOptions = svcDefServiceWithAssignedId.objectToJson(dataMaskResource);
+			for(RangerResourceDef resource : dataMaskResources) {
+				if(StringUtils.equals(resource.getName(), xxResourceDef.getName())) {
+					dataMaskOptions = svcDefServiceWithAssignedId.objectToJson(resource);
 					break;
 				}
 			}
 
-			if(! StringUtils.equals(dataMaskOptions, xxResourceDef.getDataMaskOptions())) {
+			for(RangerResourceDef resource : rowFilterResources) {
+				if(StringUtils.equals(resource.getName(), xxResourceDef.getName())) {
+					rowFilterOptions = svcDefServiceWithAssignedId.objectToJson(resource);
+					break;
+				}
+			}
+
+			if(!StringUtils.equals(dataMaskOptions, xxResourceDef.getDataMaskOptions()) ||
+			   !StringUtils.equals(rowFilterOptions, xxResourceDef.getRowFilterOptions())) {
 				xxResourceDef.setDataMaskOptions(dataMaskOptions);
+				xxResourceDef.setRowFilterOptions(rowFilterOptions);
 				xxResDefDao.update(xxResourceDef);
 			}
 		}
@@ -1596,6 +1632,7 @@ public class ServiceDBStore extends AbstractServiceStore {
 		List<RangerPolicyItem> allowExceptions = policy.getAllowExceptions();
 		List<RangerPolicyItem> denyExceptions  = policy.getDenyExceptions();
 		List<RangerDataMaskPolicyItem> dataMaskItems  = policy.getDataMaskPolicyItems();
+		List<RangerRowFilterPolicyItem> rowFilterItems = policy.getRowFilterPolicyItems();
 
 		policy.setVersion(Long.valueOf(1));
 		updatePolicySignature(policy);
@@ -1620,7 +1657,8 @@ public class ServiceDBStore extends AbstractServiceStore {
 		createNewPolicyItemsForPolicy(policy, xCreatedPolicy, denyPolicyItems, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY);
 		createNewPolicyItemsForPolicy(policy, xCreatedPolicy, allowExceptions, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS);
 		createNewPolicyItemsForPolicy(policy, xCreatedPolicy, denyExceptions, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS);
-		createNewDataMaskPolicyItemsForPolicy(policy, xCreatedPolicy, dataMaskItems, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATA_MASKING);
+		createNewDataMaskPolicyItemsForPolicy(policy, xCreatedPolicy, dataMaskItems, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATAMASK);
+		createNewRowFilterPolicyItemsForPolicy(policy, xCreatedPolicy, rowFilterItems, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ROWFILTER);
 		handlePolicyUpdate(service);
 		RangerPolicy createdPolicy = policyService.getPopulatedViewObject(xCreatedPolicy);
 		dataHistService.createObjectDataHistory(createdPolicy, RangerDataHistService.ACTION_CREATE);
@@ -1674,7 +1712,8 @@ public class ServiceDBStore extends AbstractServiceStore {
 		List<RangerPolicyItem> allowExceptions = policy.getAllowExceptions();
 		List<RangerPolicyItem> denyExceptions  = policy.getDenyExceptions();
 		List<RangerDataMaskPolicyItem> dataMaskPolicyItems = policy.getDataMaskPolicyItems();
-		
+		List<RangerRowFilterPolicyItem> rowFilterItems = policy.getRowFilterPolicyItems();
+
 		policy.setCreateTime(xxExisting.getCreateTime());
 		policy.setGuid(xxExisting.getGuid());
 		policy.setVersion(xxExisting.getVersion());
@@ -1694,7 +1733,8 @@ public class ServiceDBStore extends AbstractServiceStore {
 		createNewPolicyItemsForPolicy(policy, newUpdPolicy, denyPolicyItems, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY);
 		createNewPolicyItemsForPolicy(policy, newUpdPolicy, allowExceptions, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS);
 		createNewPolicyItemsForPolicy(policy, newUpdPolicy, denyExceptions, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS);
-		createNewDataMaskPolicyItemsForPolicy(policy, newUpdPolicy, dataMaskPolicyItems, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATA_MASKING);
+		createNewDataMaskPolicyItemsForPolicy(policy, newUpdPolicy, dataMaskPolicyItems, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATAMASK);
+		createNewRowFilterPolicyItemsForPolicy(policy, newUpdPolicy, rowFilterItems, xServiceDef, RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ROWFILTER);
 
 		handlePolicyUpdate(service);
 		RangerPolicy updPolicy = policyService.getPopulatedViewObject(newUpdPolicy);
@@ -2284,7 +2324,7 @@ public class ServiceDBStore extends AbstractServiceStore {
 		}
 	}
 
-	private XXPolicyItem createNewPolicyItemForPolicy(RangerPolicy policy, XXPolicy xPolicy, RangerPolicy.RangerPolicyItem policyItem, XXServiceDef xServiceDef, int itemOrder, int policyItemType) throws Exception {
+	private XXPolicyItem createNewPolicyItemForPolicy(RangerPolicy policy, XXPolicy xPolicy, RangerPolicyItem policyItem, XXServiceDef xServiceDef, int itemOrder, int policyItemType) throws Exception {
 		XXPolicyItem xPolicyItem = new XXPolicyItem();
 
 		xPolicyItem = (XXPolicyItem) rangerAuditFields.populateAuditFields(xPolicyItem, xPolicy);
@@ -2393,7 +2433,7 @@ public class ServiceDBStore extends AbstractServiceStore {
 
 				XXPolicyItem xPolicyItem = createNewPolicyItemForPolicy(policy, xPolicy, policyItem, xServiceDef, itemOrder, policyItemType);
 
-				RangerPolicy.RangerPolicyItemDataMaskInfo dataMaskInfo = policyItem.getDataMaskInfo();
+				RangerPolicyItemDataMaskInfo dataMaskInfo = policyItem.getDataMaskInfo();
 
 				if(dataMaskInfo != null) {
 					XXDataMaskTypeDef dataMaskDef = daoMgr.getXXDataMaskTypeDef().findByNameAndServiceId(dataMaskInfo.getDataMaskType(), xPolicy.getService());
@@ -2404,7 +2444,7 @@ public class ServiceDBStore extends AbstractServiceStore {
 
 					XXPolicyItemDataMaskInfo xxDataMaskInfo = new XXPolicyItemDataMaskInfo();
 
-					xxDataMaskInfo.setPolicyitemid(xPolicyItem.getId());
+					xxDataMaskInfo.setPolicyItemId(xPolicyItem.getId());
 					xxDataMaskInfo.setType(dataMaskDef.getId());
 					xxDataMaskInfo.setConditionExpr(dataMaskInfo.getConditionExpr());
 					xxDataMaskInfo.setValueExpr(dataMaskInfo.getValueExpr());
@@ -2415,6 +2455,27 @@ public class ServiceDBStore extends AbstractServiceStore {
 		}
 	}
 
+	private void createNewRowFilterPolicyItemsForPolicy(RangerPolicy policy, XXPolicy xPolicy, List<RangerRowFilterPolicyItem> policyItems, XXServiceDef xServiceDef, int policyItemType) throws Exception {
+		if(CollectionUtils.isNotEmpty(policyItems)) {
+			for (int itemOrder = 0; itemOrder < policyItems.size(); itemOrder++) {
+				RangerRowFilterPolicyItem policyItem = policyItems.get(itemOrder);
+
+				XXPolicyItem xPolicyItem = createNewPolicyItemForPolicy(policy, xPolicy, policyItem, xServiceDef, itemOrder, policyItemType);
+
+				RangerPolicyItemRowFilterInfo dataMaskInfo = policyItem.getRowFilterInfo();
+
+				if(dataMaskInfo != null) {
+					XXPolicyItemRowFilterInfo xxRowFilterInfo = new XXPolicyItemRowFilterInfo();
+
+					xxRowFilterInfo.setPolicyItemId(xPolicyItem.getId());
+					xxRowFilterInfo.setFilterExpr(dataMaskInfo.getFilterExpr());
+
+					xxRowFilterInfo = daoMgr.getXXPolicyItemRowFilterInfo().create(xxRowFilterInfo);
+				}
+			}
+		}
+	}
+
 	private void createNewResourcesForPolicy(RangerPolicy policy, XXPolicy xPolicy, Map<String, RangerPolicyResource> resources) throws Exception {
 		
 		for (Entry<String, RangerPolicyResource> resource : resources.entrySet()) {
@@ -2491,6 +2552,12 @@ public class ServiceDBStore extends AbstractServiceStore {
 				polItemDataMaskInfoDao.remove(dataMaskInfo);
 			}
 
+			XXPolicyItemRowFilterInfoDao polItemRowFilterInfoDao = daoMgr.getXXPolicyItemRowFilterInfo();
+			List<XXPolicyItemRowFilterInfo> rowFilterInfos = polItemRowFilterInfoDao.findByPolicyItemId(polItemId);
+			for(XXPolicyItemRowFilterInfo rowFilterInfo : rowFilterInfos) {
+				polItemRowFilterInfoDao.remove(rowFilterInfo);
+			}
+
 			policyItemDao.remove(policyItem);
 		}
 		return true;
@@ -2628,4 +2695,23 @@ public class ServiceDBStore extends AbstractServiceStore {
 		return ret;
 	}
 
+	private boolean isAccessTypeInList(String accessType, List<XXAccessTypeDef> xAccessTypeDefs) {
+		for(XXAccessTypeDef xxAccessTypeDef : xAccessTypeDefs) {
+			if(StringUtils.equals(xxAccessTypeDef.getName(), accessType)) {
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	private boolean isResourceInList(String resource, List<XXResourceDef> xResourceDefs) {
+		for(XXResourceDef xResourceDef : xResourceDefs) {
+			if(StringUtils.equals(xResourceDef.getName(), resource)) {
+				return true;
+			}
+		}
+
+		return false;
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
index e9c8394..6f53a24 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
@@ -34,7 +34,9 @@ import org.apache.ranger.entity.XXGroupPermission;
 import org.apache.ranger.entity.XXModuleDef;
 import org.apache.ranger.entity.XXUserPermission;
 import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerDataMaskPolicyItem;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerRowFilterPolicyItem;
 import org.apache.ranger.service.RangerPolicyService;
 import org.apache.ranger.service.XGroupPermissionService;
 import org.apache.ranger.service.XModuleDefService;
@@ -1522,6 +1524,14 @@ public class XUserMgr extends XUserMgrBase {
 				removeUserGroupReferences(denyExceptions,null,vXGroup.getName());
 				rangerPolicy.setDenyExceptions(denyExceptions);
 
+				List<RangerDataMaskPolicyItem> dataMaskItems = rangerPolicy.getDataMaskPolicyItems();
+				removeUserGroupReferences(dataMaskItems,null,vXGroup.getName());
+				rangerPolicy.setDataMaskPolicyItems(dataMaskItems);
+
+				List<RangerRowFilterPolicyItem> rowFilterItems = rangerPolicy.getRowFilterPolicyItems();
+				removeUserGroupReferences(rowFilterItems,null,vXGroup.getName());
+				rangerPolicy.setRowFilterPolicyItems(rowFilterItems);
+
 				try {
 					svcStore.updatePolicy(rangerPolicy);
 				} catch (Throwable excp) {
@@ -1694,6 +1704,14 @@ public class XUserMgr extends XUserMgrBase {
 				removeUserGroupReferences(denyExceptions,vXUser.getName(),null);
 				rangerPolicy.setDenyExceptions(denyExceptions);
 
+				List<RangerDataMaskPolicyItem> dataMaskItems = rangerPolicy.getDataMaskPolicyItems();
+				removeUserGroupReferences(dataMaskItems,vXUser.getName(),null);
+				rangerPolicy.setDataMaskPolicyItems(dataMaskItems);
+
+				List<RangerRowFilterPolicyItem> rowFilterItems = rangerPolicy.getRowFilterPolicyItems();
+				removeUserGroupReferences(rowFilterItems,vXUser.getName(),null);
+				rangerPolicy.setRowFilterPolicyItems(rowFilterItems);
+
 				try{
 					svcStore.updatePolicy(rangerPolicy);
 				}catch(Throwable excp) {
@@ -1761,9 +1779,9 @@ public class XUserMgr extends XUserMgrBase {
 		}
 	}
 
-	private void removeUserGroupReferences(List<RangerPolicyItem> policyItems, String user, String group) {
-		List<RangerPolicyItem> itemsToRemove = null;
-		for(RangerPolicyItem policyItem : policyItems) {
+	private <T extends RangerPolicyItem> void removeUserGroupReferences(List<T> policyItems, String user, String group) {
+		List<T> itemsToRemove = null;
+		for(T policyItem : policyItems) {
 			if(!StringUtil.isEmpty(user)) {
 				policyItem.getUsers().remove(user);
 			}
@@ -1772,7 +1790,7 @@ public class XUserMgr extends XUserMgrBase {
 			}
 			if(policyItem.getUsers().isEmpty() && policyItem.getGroups().isEmpty()) {
 				if(itemsToRemove == null) {
-					itemsToRemove = new ArrayList<RangerPolicyItem>();
+					itemsToRemove = new ArrayList<T>();
 				}
 				itemsToRemove.add(policyItem);
 			}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/src/main/java/org/apache/ranger/common/AppConstants.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/common/AppConstants.java b/security-admin/src/main/java/org/apache/ranger/common/AppConstants.java
index 6988750..3851069 100644
--- a/security-admin/src/main/java/org/apache/ranger/common/AppConstants.java
+++ b/security-admin/src/main/java/org/apache/ranger/common/AppConstants.java
@@ -583,11 +583,15 @@ public class AppConstants extends RangerCommonEnums {
 	 * CLASS_TYPE_RANGER_POLICY_ITEM_DATAMASK_INFO is an element of enum ClassTypes. Its value is "CLASS_TYPE_RANGER_POLICY_ITEM_DATAMASK_INFO".
 	 */
 	public static final int CLASS_TYPE_RANGER_POLICY_ITEM_DATAMASK_INFO = 1050;
+	/**
+	 * CLASS_TYPE_RANGER_POLICY_ITEM_ROWFILTER_INFO is an element of enum ClassTypes. Its value is "CLASS_TYPE_RANGER_POLICY_ITEM_ROWFILTER_INFO".
+	 */
+	public static final int CLASS_TYPE_RANGER_POLICY_ITEM_ROWFILTER_INFO = 1051;
 
 	/**
 	 * Max value for enum ClassTypes_MAX
 	 */
-	public static final int ClassTypes_MAX = 1050;
+	public static final int ClassTypes_MAX = 1051;
 	
 	/***************************************************************
 	 * Enum values for Default SortOrder

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java b/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java
index 5431553..6559850 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java
@@ -192,6 +192,9 @@ public abstract class RangerDaoManagerBase {
 		if (classType == AppConstants.CLASS_TYPE_RANGER_POLICY_ITEM_DATAMASK_INFO) {
 			return getXXPolicyItemDataMaskInfo();
 		}
+		if (classType== AppConstants.CLASS_TYPE_RANGER_POLICY_ITEM_ROWFILTER_INFO) {
+			return getXXPolicyItemRowFilterInfo();
+		}
 
 		logger.error("No DaoManager found for classType=" + classType, new Throwable());
 		return null;
@@ -352,6 +355,9 @@ public abstract class RangerDaoManagerBase {
 		if (className.equals("XXPolicyItemDataMaskInfo")) {
 			return getXXPolicyItemDataMaskInfo();
 		}
+		if (className.equals("XXPolicyItemRowFilterInfo")) {
+			return getXXPolicyItemRowFilterInfo();
+		}
 
 		logger.error("No DaoManager found for className=" + className, new Throwable());
 		return null;
@@ -566,5 +572,9 @@ public abstract class RangerDaoManagerBase {
 		return new XXPolicyItemDataMaskInfoDao(this);
 	}
 
+	public XXPolicyItemRowFilterInfoDao getXXPolicyItemRowFilterInfo() {
+		return new XXPolicyItemRowFilterInfoDao(this);
+	}
+
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyItemRowFilterInfoDao.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXPolicyItemRowFilterInfoDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyItemRowFilterInfoDao.java
new file mode 100644
index 0000000..4618e7d
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXPolicyItemRowFilterInfoDao.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.db;
+
+import org.apache.ranger.common.db.BaseDao;
+import org.apache.ranger.entity.XXPolicyItemRowFilterInfo;
+
+import javax.persistence.NoResultException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class XXPolicyItemRowFilterInfoDao extends BaseDao<XXPolicyItemRowFilterInfo> {
+
+	public XXPolicyItemRowFilterInfoDao(RangerDaoManagerBase daoManager) {
+		super(daoManager);
+	}
+	
+	public List<XXPolicyItemRowFilterInfo> findByPolicyItemId(Long polItemId) {
+		if(polItemId == null) {
+			return new ArrayList<XXPolicyItemRowFilterInfo>();
+		}
+		try {
+			return getEntityManager()
+					.createNamedQuery("XXPolicyItemRowFilterInfo.findByPolicyItemId", tClass)
+					.setParameter("polItemId", polItemId).getResultList();
+		} catch (NoResultException e) {
+			return new ArrayList<XXPolicyItemRowFilterInfo>();
+		}
+	}
+
+	public List<XXPolicyItemRowFilterInfo> findByPolicyId(Long policyId) {
+		if(policyId == null) {
+			return new ArrayList<XXPolicyItemRowFilterInfo>();
+		}
+		try {
+			return getEntityManager()
+					.createNamedQuery("XXPolicyItemRowFilterInfo.findByPolicyId", tClass)
+					.setParameter("policyId", policyId).getResultList();
+		} catch (NoResultException e) {
+			return new ArrayList<XXPolicyItemRowFilterInfo>();
+		}
+	}
+
+	public List<XXPolicyItemRowFilterInfo> findByServiceId(Long serviceId) {
+		if(serviceId == null) {
+			return new ArrayList<XXPolicyItemRowFilterInfo>();
+		}
+		try {
+			return getEntityManager()
+					.createNamedQuery("XXPolicyItemRowFilterInfo.findByServiceId", tClass)
+					.setParameter("serviceId", serviceId).getResultList();
+		} catch (NoResultException e) {
+			return new ArrayList<XXPolicyItemRowFilterInfo>();
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/src/main/java/org/apache/ranger/entity/XXAccessTypeDef.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/entity/XXAccessTypeDef.java b/security-admin/src/main/java/org/apache/ranger/entity/XXAccessTypeDef.java
index 5bc22e0..719ada1 100644
--- a/security-admin/src/main/java/org/apache/ranger/entity/XXAccessTypeDef.java
+++ b/security-admin/src/main/java/org/apache/ranger/entity/XXAccessTypeDef.java
@@ -103,6 +103,15 @@ public class XXAccessTypeDef extends XXDBBase implements java.io.Serializable {
 	protected String dataMaskOptions;
 
 	/**
+	 * rowFilterOptions of the XXAccessTypeDef
+	 * <ul>
+	 * </ul>
+	 *
+	 */
+	@Column(name = "rowfilter_options")
+	protected String rowFilterOptions;
+
+	/**
 	 * This method sets the value to the member attribute <b> id</b> . You
 	 * cannot set null to the attribute.
 	 * 
@@ -250,6 +259,10 @@ public class XXAccessTypeDef extends XXDBBase implements java.io.Serializable {
 		this.dataMaskOptions = dataMaskOptions;
 	}
 
+	public String getRowFilterOptions() { return rowFilterOptions; }
+
+	public void setRowFilterOptions(String rowFilterOptions) { this.rowFilterOptions = rowFilterOptions; }
+
 	/*
 	 * (non-Javadoc)
 	 * 
@@ -326,6 +339,13 @@ public class XXAccessTypeDef extends XXDBBase implements java.io.Serializable {
 		} else if (!dataMaskOptions.equals(other.dataMaskOptions)) {
 			return false;
 		}
+		if (rowFilterOptions == null) {
+			if (other.rowFilterOptions != null) {
+				return false;
+			}
+		} else if (!rowFilterOptions.equals(other.rowFilterOptions)) {
+			return false;
+		}
 		return true;
 	}
 
@@ -338,7 +358,8 @@ public class XXAccessTypeDef extends XXDBBase implements java.io.Serializable {
 	public String toString() {
 		return "XXAccessTypeDef [" + super.toString() + " id=" + id
 				+ ", defId=" + defId + ", itemId=" + itemId + ", name=" + name + ", label=" + label
-				+ ", rbKeyLabel=" + rbKeyLabel + ", dataMaskOptions=" + dataMaskOptions + ", order=" + order + "]";
+				+ ", rbKeyLabel=" + rbKeyLabel + ", dataMaskOptions=" + dataMaskOptions
+				+ ", rowFilterOptions=" + rowFilterOptions + ", order=" + order + "]";
 	}
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/src/main/java/org/apache/ranger/entity/XXPolicyItemDataMaskInfo.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/entity/XXPolicyItemDataMaskInfo.java b/security-admin/src/main/java/org/apache/ranger/entity/XXPolicyItemDataMaskInfo.java
index 391f5a8..5561255 100644
--- a/security-admin/src/main/java/org/apache/ranger/entity/XXPolicyItemDataMaskInfo.java
+++ b/security-admin/src/main/java/org/apache/ranger/entity/XXPolicyItemDataMaskInfo.java
@@ -41,16 +41,6 @@ public class XXPolicyItemDataMaskInfo extends XXDBBase implements
 	protected Long id;
 
 	/**
-	 * Global Id for the object
-	 * <ul>
-	 * <li>The maximum length for this attribute is <b>512</b>.
-	 * </ul>
-	 *
-	 */
-	@Column(name = "guid", unique = true, nullable = false, length = 512)
-	protected String GUID;
-	
-	/**
 	 * policyItemId of the XXPolicyItemDataMaskInfo
 	 * <ul>
 	 * </ul>
@@ -107,28 +97,13 @@ public class XXPolicyItemDataMaskInfo extends XXDBBase implements
 	}
 
 	/**
-	 * @return the gUID
-	 */
-	public String getGUID() {
-		return GUID;
-	}
-
-	/**
-	 * @param gUID
-	 *            the gUID to set
-	 */
-	public void setGUID(String gUID) {
-		GUID = gUID;
-	}
-
-	/**
 	 * This method sets the value to the member attribute <b> policyItemId</b> .
 	 * You cannot set null to the attribute.
 	 * 
 	 * @param policyItemId
 	 *            Value to set member attribute <b> policyItemId</b>
 	 */
-	public void setPolicyitemid(Long policyItemId) {
+	public void setPolicyItemId(Long policyItemId) {
 		this.policyItemId = policyItemId;
 	}
 
@@ -137,7 +112,7 @@ public class XXPolicyItemDataMaskInfo extends XXDBBase implements
 	 * 
 	 * @return Date - value of member attribute <b>policyItemId</b> .
 	 */
-	public Long getPolicyitemid() {
+	public Long getPolicyItemId() {
 		return this.policyItemId;
 	}
 
@@ -256,13 +231,6 @@ public class XXPolicyItemDataMaskInfo extends XXDBBase implements
 		} else if (!type.equals(other.type)) {
 			return false;
 		}
-		if (GUID == null) {
-			if (other.GUID != null) {
-				return false;
-			}
-		} else if (!GUID.equals(other.GUID)) {
-			return false;
-		}
 		return true;
 	}
 
@@ -274,9 +242,8 @@ public class XXPolicyItemDataMaskInfo extends XXDBBase implements
 	@Override
 	public String toString() {
 		return "XXPolicyItemDataMaskInfo [" + super.toString() + " id=" + id
-				+ ", guid=" + GUID + ", policyItemId="
-				+ policyItemId + ", type=" + type + ", conditionExpr=" + conditionExpr
-				+ ", valueExpr=" + valueExpr + "]";
+				+ ", policyItemId=" + policyItemId + ", type=" + type
+				+ ", conditionExpr=" + conditionExpr + ", valueExpr=" + valueExpr + "]";
 	}
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/src/main/java/org/apache/ranger/entity/XXPolicyItemRowFilterInfo.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/entity/XXPolicyItemRowFilterInfo.java b/security-admin/src/main/java/org/apache/ranger/entity/XXPolicyItemRowFilterInfo.java
new file mode 100644
index 0000000..6a63ad1
--- /dev/null
+++ b/security-admin/src/main/java/org/apache/ranger/entity/XXPolicyItemRowFilterInfo.java
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger.entity;
+
+import javax.persistence.*;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@Entity
+@Cacheable
+@XmlRootElement
+@Table(name = "x_policy_item_rowfilter")
+public class XXPolicyItemRowFilterInfo extends XXDBBase implements
+		java.io.Serializable {
+	private static final long serialVersionUID = 1L;
+	/**
+	 * id of the XXPolicyItemRowFilterInfo
+	 * <ul>
+	 * </ul>
+	 *
+	 */
+	@Id
+	@SequenceGenerator(name = "x_policy_item_rowfilter_SEQ", sequenceName = "x_policy_item_rowfilter_SEQ", allocationSize = 1)
+	@GeneratedValue(strategy = GenerationType.AUTO, generator = "x_policy_item_rowfilter_SEQ")
+	@Column(name = "id")
+	protected Long id;
+
+	/**
+	 * policyItemId of the XXPolicyItemRowFilterInfo
+	 * <ul>
+	 * </ul>
+	 *
+	 */
+	@Column(name = "policy_item_id")
+	protected Long policyItemId;
+
+	/**
+	 * filter_expr of the XXPolicyItemRowFilterInfo
+	 * <ul>
+	 * </ul>
+	 *
+	 */
+	@Column(name = "filter_expr")
+	protected String filterExpr;
+
+	/**
+	 * This method sets the value to the member attribute <b> id</b> . You
+	 * cannot set null to the attribute.
+	 * 
+	 * @param id
+	 *            Value to set member attribute <b> id</b>
+	 */
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	/**
+	 * Returns the value for the member attribute <b>id</b>
+	 * 
+	 * @return Long - value of member attribute <b>id</b> .
+	 */
+	public Long getId() {
+		return this.id;
+	}
+
+	/**
+	 * This method sets the value to the member attribute <b> policyItemId</b> .
+	 * You cannot set null to the attribute.
+	 * 
+	 * @param policyItemId
+	 *            Value to set member attribute <b> policyItemId</b>
+	 */
+	public void setPolicyItemId(Long policyItemId) {
+		this.policyItemId = policyItemId;
+	}
+
+	/**
+	 * Returns the value for the member attribute <b>policyItemId</b>
+	 * 
+	 * @return Long - value of member attribute <b>policyItemId</b> .
+	 */
+	public Long getPolicyItemId() {
+		return this.policyItemId;
+	}
+
+	/**
+	 * This method sets the value to the member attribute <b> filterExpr</b> .
+	 * You cannot set null to the attribute.
+	 * 
+	 * @param filterExpr
+	 *            Value to set member attribute <b> filterExpr</b>
+	 */
+	public void setFilterExpr(String filterExpr) {
+		this.filterExpr = filterExpr;
+	}
+
+	/**
+	 * Returns the value for the member attribute <b>filterExpr</b>
+	 *
+	 * @return String - value of member attribute <b>filterExpr</b> .
+	 */
+	public String getFilterExpr() {
+		return this.filterExpr;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if (!super.equals(obj)) {
+			return false;
+		}
+		if (this == obj) {
+			return true;
+		}
+		if (!super.equals(obj)) {
+			return false;
+		}
+		if (getClass() != obj.getClass()) {
+			return false;
+		}
+		XXPolicyItemRowFilterInfo other = (XXPolicyItemRowFilterInfo) obj;
+		if (id == null) {
+			if (other.id != null) {
+				return false;
+			}
+		} else if (!id.equals(other.id)) {
+			return false;
+		}
+		if (filterExpr == null) {
+			if (other.filterExpr != null) {
+				return false;
+			}
+		} else if (!filterExpr.equals(other.filterExpr)) {
+			return false;
+		}
+		if (policyItemId == null) {
+			if (other.policyItemId != null) {
+				return false;
+			}
+		} else if (!policyItemId.equals(other.policyItemId)) {
+			return false;
+		}
+		return true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return "XXPolicyItemDataMaskInfo [" + super.toString() + " id=" + id
+				+ ", policyItemId=" + policyItemId + ", filterExpr=" + filterExpr + "]";
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/2c7f617b/security-admin/src/main/java/org/apache/ranger/entity/XXResourceDef.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/entity/XXResourceDef.java b/security-admin/src/main/java/org/apache/ranger/entity/XXResourceDef.java
index 6679c35..28ee4e7 100644
--- a/security-admin/src/main/java/org/apache/ranger/entity/XXResourceDef.java
+++ b/security-admin/src/main/java/org/apache/ranger/entity/XXResourceDef.java
@@ -238,6 +238,15 @@ public class XXResourceDef extends XXDBBase implements java.io.Serializable {
 	protected String dataMaskOptions;
 
 	/**
+	 * rowFilterOptions of the XXAccessTypeDef
+	 * <ul>
+	 * </ul>
+	 *
+	 */
+	@Column(name = "rowfilter_options")
+	protected String rowFilterOptions;
+
+	/**
 	 * This method sets the value to the member attribute <b> id</b> . You
 	 * cannot set null to the attribute.
 	 * 
@@ -661,6 +670,10 @@ public class XXResourceDef extends XXDBBase implements java.io.Serializable {
 		this.dataMaskOptions = dataMaskOptions;
 	}
 
+	public String getRowFilterOptions() { return rowFilterOptions; }
+
+	public void setRowFilterOptions(String rowFilterOptions) { this.rowFilterOptions = rowFilterOptions; }
+
 	/*
 	 * (non-Javadoc)
 	 * 
@@ -803,6 +816,13 @@ public class XXResourceDef extends XXDBBase implements java.io.Serializable {
 		} else if (!dataMaskOptions.equals(other.dataMaskOptions)) {
 			return false;
 		}
+		if (rowFilterOptions == null) {
+			if (other.rowFilterOptions != null) {
+				return false;
+			}
+		} else if (!rowFilterOptions.equals(other.rowFilterOptions)) {
+			return false;
+		}
 		return true;
 	}
 
@@ -829,6 +849,7 @@ public class XXResourceDef extends XXDBBase implements java.io.Serializable {
 				+ ", rbKeyValidationMessage=" + rbKeyValidationMessage
 				+ ", order=" + order
 				+ ", dataMaskOptions=" + dataMaskOptions
+				+ ", rowFilterOptions=" + rowFilterOptions
 				+ "]";
 	}