diff --git a/ql/src/java/org/apache/hadoop/hive/ql/metadata/SessionHiveMetaStoreClient.java b/ql/src/java/org/apache/hadoop/hive/ql/metadata/SessionHiveMetaStoreClient.java index 3bb93ed60d1c..6621aacf57ef 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/metadata/SessionHiveMetaStoreClient.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/metadata/SessionHiveMetaStoreClient.java @@ -1705,10 +1705,9 @@ private String generateJDOFilter(org.apache.hadoop.hive.metastore.api.Table tabl assert table != null; ExpressionTree.FilterBuilder filterBuilder = new ExpressionTree.FilterBuilder(true); Map params = new HashMap<>(); - exprTree.generateJDOFilterFragment(conf, params, filterBuilder, table.getPartitionKeys()); + exprTree.accept(new ExpressionTree.JDOFilterGenerator(conf, + table.getPartitionKeys(), filterBuilder, params)); StringBuilder stringBuilder = new StringBuilder(filterBuilder.getFilter()); - // replace leading && - stringBuilder.replace(0, 4, ""); params.entrySet().stream().forEach(e -> { int index = stringBuilder.indexOf(e.getKey()); stringBuilder.replace(index, index + e.getKey().length(), "\"" + e.getValue().toString() + "\""); diff --git a/ql/src/test/queries/clientpositive/partition_timestamp3.q b/ql/src/test/queries/clientpositive/partition_timestamp3.q new file mode 100644 index 000000000000..b408848d6226 --- /dev/null +++ b/ql/src/test/queries/clientpositive/partition_timestamp3.q @@ -0,0 +1,6 @@ +--! qt:timezone:Europe/Paris +DROP TABLE IF EXISTS payments; +CREATE EXTERNAL TABLE payments (card string) PARTITIONED BY(txn_datetime TIMESTAMP) STORED AS ORC; +INSERT into payments VALUES('3333-4444-2222-9999', '2023-03-26 02:30:00'), ('3333-4444-2222-9999', '2023-03-26 03:30:00'); +SELECT * FROM payments WHERE txn_datetime = '2023-03-26 02:30:00'; +SELECT * FROM payments WHERE txn_datetime = '2023-03-26 03:30:00'; diff --git a/ql/src/test/results/clientpositive/llap/partition_timestamp3.q.out b/ql/src/test/results/clientpositive/llap/partition_timestamp3.q.out new file mode 100644 index 000000000000..847ec070fabd --- /dev/null +++ b/ql/src/test/results/clientpositive/llap/partition_timestamp3.q.out @@ -0,0 +1,48 @@ +PREHOOK: query: DROP TABLE IF EXISTS payments +PREHOOK: type: DROPTABLE +PREHOOK: Output: database:default +POSTHOOK: query: DROP TABLE IF EXISTS payments +POSTHOOK: type: DROPTABLE +POSTHOOK: Output: database:default +PREHOOK: query: CREATE EXTERNAL TABLE payments (card string) PARTITIONED BY(txn_datetime TIMESTAMP) STORED AS ORC +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@payments +POSTHOOK: query: CREATE EXTERNAL TABLE payments (card string) PARTITIONED BY(txn_datetime TIMESTAMP) STORED AS ORC +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@payments +PREHOOK: query: INSERT into payments VALUES('3333-4444-2222-9999', '2023-03-26 02:30:00'), ('3333-4444-2222-9999', '2023-03-26 03:30:00') +PREHOOK: type: QUERY +PREHOOK: Input: _dummy_database@_dummy_table +PREHOOK: Output: default@payments +POSTHOOK: query: INSERT into payments VALUES('3333-4444-2222-9999', '2023-03-26 02:30:00'), ('3333-4444-2222-9999', '2023-03-26 03:30:00') +POSTHOOK: type: QUERY +POSTHOOK: Input: _dummy_database@_dummy_table +POSTHOOK: Output: default@payments +POSTHOOK: Output: default@payments@txn_datetime=2023-03-26 02%3A30%3A00 +POSTHOOK: Output: default@payments@txn_datetime=2023-03-26 03%3A30%3A00 +POSTHOOK: Lineage: payments PARTITION(txn_datetime=2023-03-26 02:30:00).card SCRIPT [] +POSTHOOK: Lineage: payments PARTITION(txn_datetime=2023-03-26 03:30:00).card SCRIPT [] +PREHOOK: query: SELECT * FROM payments WHERE txn_datetime = '2023-03-26 02:30:00' +PREHOOK: type: QUERY +PREHOOK: Input: default@payments +PREHOOK: Input: default@payments@txn_datetime=2023-03-26 02%3A30%3A00 +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM payments WHERE txn_datetime = '2023-03-26 02:30:00' +POSTHOOK: type: QUERY +POSTHOOK: Input: default@payments +POSTHOOK: Input: default@payments@txn_datetime=2023-03-26 02%3A30%3A00 +#### A masked pattern was here #### +3333-4444-2222-9999 2023-03-26 02:30:00 +PREHOOK: query: SELECT * FROM payments WHERE txn_datetime = '2023-03-26 03:30:00' +PREHOOK: type: QUERY +PREHOOK: Input: default@payments +PREHOOK: Input: default@payments@txn_datetime=2023-03-26 03%3A30%3A00 +#### A masked pattern was here #### +POSTHOOK: query: SELECT * FROM payments WHERE txn_datetime = '2023-03-26 03:30:00' +POSTHOOK: type: QUERY +POSTHOOK: Input: default@payments +POSTHOOK: Input: default@payments@txn_datetime=2023-03-26 03%3A30%3A00 +#### A masked pattern was here #### +3333-4444-2222-9999 2023-03-26 03:30:00 diff --git a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/DatabaseProduct.java b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/DatabaseProduct.java index 6e04bf0d6f78..51aca96f4583 100644 --- a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/DatabaseProduct.java +++ b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/DatabaseProduct.java @@ -18,6 +18,7 @@ package org.apache.hadoop.hive.metastore; +import java.sql.Date; import java.sql.SQLException; import java.sql.SQLIntegrityConstraintViolationException; import java.sql.SQLTransactionRollbackException; @@ -36,6 +37,7 @@ import org.apache.hadoop.hive.metastore.conf.MetastoreConf; import org.apache.hadoop.hive.metastore.conf.MetastoreConf.ConfVars; import org.apache.hadoop.hive.metastore.txn.TxnUtils; +import org.apache.hadoop.hive.metastore.utils.MetaStoreUtils; import org.apache.hadoop.util.ReflectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -263,7 +265,9 @@ protected String toDate(String tableValue) { protected String toTimestamp(String tableValue) { if (isORACLE()) { - return "TO_TIMESTAMP(" + tableValue + ", 'YYYY-MM-DD HH:mm:ss')"; + return "TO_TIMESTAMP(" + tableValue + ", 'YYYY-MM-DD HH:mi:ss')"; + } else if (isSQLSERVER()) { + return "CONVERT(DATETIME, " + tableValue + ")"; } else { return "cast(" + tableValue + " as TIMESTAMP)"; } @@ -748,6 +752,26 @@ public Object getBoolean(boolean val) { return val; } + public Object convertDateValue(Object dateValue) { + assert dateValue instanceof String; + Date date = MetaStoreUtils.convertStringToDate((String)dateValue); + Object result = MetaStoreUtils.convertDateToString(date); + return result; + } + + public Object convertTimestampValue(Object timestampValue) { + assert timestampValue instanceof String; + Timestamp timestamp = MetaStoreUtils.convertStringToTimestamp((String)timestampValue); + if (isPOSTGRES() || isSQLSERVER()) { + // The timestampValue looks valid now, for Postgres or SQLServer, return timestampValue as it is, + // otherwise we may run into different results on SQL and JDO, check the partition_timestamp3.q + // for such case. + return timestampValue; + } + Object result = MetaStoreUtils.convertTimestampToString(timestamp); + return result; + } + // This class implements the Configurable interface for the benefit // of "plugin" instances created via reflection (see invocation of // ReflectionUtils.newInstance in method determineDatabaseProduct) diff --git a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreDirectSql.java b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreDirectSql.java index 97956660791a..559d6057d9b2 100644 --- a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreDirectSql.java +++ b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/MetaStoreDirectSql.java @@ -32,10 +32,8 @@ import static org.apache.hadoop.hive.metastore.ColumnType.VARCHAR_TYPE_NAME; import java.sql.Connection; -import java.sql.Date; import java.sql.SQLException; import java.sql.Statement; -import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -1323,7 +1321,7 @@ public static FilterType fromClass(Object value){ @Override public void visit(LeafNode node) throws MetaException { int partColCount = partitionKeys.size(); - int partColIndex = node.getPartColIndexForFilter(partitionKeys, filterBuffer); + int partColIndex = LeafNode.getPartColIndexForFilter(node.keyName, partitionKeys, filterBuffer); if (filterBuffer.hasError()) { return; } @@ -1341,29 +1339,34 @@ public void visit(LeafNode node) throws MetaException { return; } + String nodeValue0 = "?"; // if Filter.g does date parsing for quoted strings, we'd need to verify there's no // type mismatch when string col is filtered by a string that looks like date. - if (colType == FilterType.Date && valType == FilterType.String) { - // Filter.g cannot parse a quoted date; try to parse date here too. + if (colType == FilterType.Date) { try { - nodeValue = MetaStoreUtils.convertStringToDate((String)nodeValue); + nodeValue = dbType.convertDateValue(nodeValue); valType = FilterType.Date; - } catch (Exception pe) { // do nothing, handled below - types will mismatch + if (dbType.isPOSTGRES()) { + nodeValue0 = "date '" + nodeValue + "'"; + nodeValue = null; + } + } catch (Exception e) { // do nothing, handled below - types will mismatch + } + } else if (colType == FilterType.Timestamp) { + try { + if (dbType.isDERBY() || dbType.isMYSQL()) { + filterBuffer.setError("Filter pushdown not supported for timestamp on " + dbType.dbType.name()); + return; + } + nodeValue = dbType.convertTimestampValue(nodeValue); + valType = FilterType.Timestamp; + if (dbType.isPOSTGRES()) { + nodeValue0 = "timestamp '" + nodeValue + "'"; + nodeValue = null; + } + } catch (Exception e) { + // The nodeValue could be '__HIVE_DEFAULT_PARTITION__' } - } - - if (colType == FilterType.Timestamp && valType == FilterType.String) { - nodeValue = MetaStoreUtils.convertStringToTimestamp((String)nodeValue); - valType = FilterType.Timestamp; - } - - // We format it so we are sure we are getting the right value - if (valType == FilterType.Date) { - // Format - nodeValue = MetaStoreUtils.convertDateToString((Date)nodeValue); - } else if (valType == FilterType.Timestamp) { - //format - nodeValue = MetaStoreUtils.convertTimestampToString((Timestamp) nodeValue); } boolean isDefaultPartition = (valType == FilterType.String) && defaultPartName.equals(nodeValue); @@ -1393,8 +1396,7 @@ public void visit(LeafNode node) throws MetaException { // Build the filter and add parameters linearly; we are traversing leaf nodes LTR. String tableValue = "\"FILTER" + partColIndex + "\".\"PART_KEY_VAL\""; - String nodeValue0 = "?"; - if (node.isReverseOrder) { + if (node.isReverseOrder && nodeValue != null) { params.add(nodeValue); } String tableColumn = tableValue; @@ -1424,14 +1426,9 @@ public void visit(LeafNode node) throws MetaException { params.add(catName.toLowerCase()); } tableValue += " then " + tableValue0 + " else null end)"; - - if (valType == FilterType.Date) { - tableValue = dbType.toDate(tableValue); - } else if (valType == FilterType.Timestamp) { - tableValue = dbType.toTimestamp(tableValue); - } } - if (!node.isReverseOrder) { + + if (!node.isReverseOrder && nodeValue != null) { params.add(nodeValue); } diff --git a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java index 436ebd932acc..cfbf63e2c81e 100644 --- a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java +++ b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java @@ -4905,7 +4905,8 @@ private String makeQueryFilterString(String catName, String dbName, Table table, params.put("catName", catName); } - tree.generateJDOFilterFragment(getConf(), params, queryBuilder, table != null ? table.getPartitionKeys() : null); + tree.accept(new ExpressionTree.JDOFilterGenerator(getConf(), + table != null ? table.getPartitionKeys() : null, queryBuilder, params)); if (queryBuilder.hasError()) { assert !isValidatedFilter; LOG.debug("JDO filter pushdown cannot be used: {}", queryBuilder.getErrorMessage()); @@ -4925,7 +4926,7 @@ private String makeQueryFilterString(String catName, String dbName, String tblNa params.put("t1", tblName); params.put("t2", dbName); params.put("t3", catName); - tree.generateJDOFilterFragment(getConf(), params, queryBuilder, partitionKeys); + tree.accept(new ExpressionTree.JDOFilterGenerator(getConf(), partitionKeys, queryBuilder, params)); if (queryBuilder.hasError()) { assert !isValidatedFilter; LOG.debug("JDO filter pushdown cannot be used: {}", queryBuilder.getErrorMessage()); diff --git a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/parser/ExpressionTree.java b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/parser/ExpressionTree.java index f2f91cbedfb7..e03273060de3 100644 --- a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/parser/ExpressionTree.java +++ b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/parser/ExpressionTree.java @@ -219,34 +219,6 @@ protected void accept(TreeVisitor visitor) throws MetaException { visitor.visit(this); } - /** - * Generates a JDO filter statement - * @param params - * A map of parameter key to values for the filter statement. - * @param filterBuffer The filter builder that is used to build filter. - * @param partitionKeys - * @throws MetaException - */ - public void generateJDOFilter(Configuration conf, - Map params, FilterBuilder filterBuffer, List partitionKeys) throws MetaException { - if (filterBuffer.hasError()) return; - if (lhs != null) { - filterBuffer.append (" ("); - lhs.generateJDOFilter(conf, params, filterBuffer, partitionKeys); - - if (rhs != null) { - if( andOr == LogicalOperator.AND ) { - filterBuffer.append(" && "); - } else { - filterBuffer.append(" || "); - } - - rhs.generateJDOFilter(conf, params, filterBuffer, partitionKeys); - } - filterBuffer.append (") "); - } - } - @Override public String toString() { return "TreeNode{" + @@ -263,10 +235,11 @@ public String toString() { public static class LeafNode extends TreeNode { public String keyName; public Operator operator; - /** Constant expression side of the operator. Can currently be a String or a Long. */ + /** + * Constant expression side of the operator. Can currently be a String or a Long. + */ public Object value; public boolean isReverseOrder = false; - private static final String PARAM_PREFIX = "hive_filter_param_"; @Override protected void accept(TreeVisitor visitor) throws MetaException { @@ -274,8 +247,100 @@ protected void accept(TreeVisitor visitor) throws MetaException { } @Override - public void generateJDOFilter(Configuration conf, Map params, - FilterBuilder filterBuilder, List partitionKeys) throws MetaException { + public String toString() { + return "LeafNode{" + + "keyName='" + keyName + '\'' + + ", operator='" + operator + '\'' + + ", value=" + value + + (isReverseOrder ? ", isReverseOrder=true" : "") + + '}'; + } + + /** + * Get partition column index in the table partition column list that + * corresponds to the key that is being filtered on by this tree node. + * @param partitionKeys list of partition keys. + * @param filterBuilder filter builder used to report error, if any. + * @return The index. + */ + public static int getPartColIndexForFilter(String partitionKeyName, + List partitionKeys, FilterBuilder filterBuilder) throws MetaException { + assert (partitionKeys.size() > 0); + int partitionColumnIndex; + for (partitionColumnIndex = 0; partitionColumnIndex < partitionKeys.size(); + ++partitionColumnIndex) { + if (partitionKeys.get(partitionColumnIndex).getName().equalsIgnoreCase(partitionKeyName)) { + break; + } + } + if( partitionColumnIndex == partitionKeys.size()) { + filterBuilder.setError("Specified key <" + partitionKeyName + + "> is not a partitioning key for the table"); + return -1; + } + + return partitionColumnIndex; + } + } + + /** + * Generate the JDOQL filter for the given expression tree + */ + public static class JDOFilterGenerator extends TreeVisitor { + + private static final String PARAM_PREFIX = "hive_filter_param_"; + + private Configuration conf; + private List partitionKeys; + // the filter builder to append to. + private FilterBuilder filterBuilder; + // the input map which is updated with the the parameterized values. + // Keys are the parameter names and values are the parameter values + private Map params; + private boolean onParsing = false; + private String keyName; + private Object value; + private Operator operator; + private boolean isReverseOrder; + + public JDOFilterGenerator(Configuration conf, List partitionKeys, + FilterBuilder filterBuilder, Map params) { + this.conf = conf; + this.partitionKeys = partitionKeys; + this.filterBuilder = filterBuilder; + this.params = params; + } + + private void beforeParsing() throws MetaException { + if (!onParsing && !filterBuilder.getFilter().isEmpty()) { + filterBuilder.append(" && "); + } + onParsing = true; + } + + @Override + protected void beginTreeNode(TreeNode node) throws MetaException { + beforeParsing(); + filterBuilder.append("( "); + } + + @Override + protected void midTreeNode(TreeNode node) throws MetaException { + filterBuilder.append((node.getAndOr() == LogicalOperator.AND) ? " && " : " || "); + } + + @Override + protected void endTreeNode(TreeNode node) throws MetaException { + filterBuilder.append(") "); + } + + @Override + protected void visit(LeafNode node) throws MetaException { + beforeParsing(); + keyName = node.keyName; + operator = node.operator; + value = node.value; + isReverseOrder = node.isReverseOrder; if (partitionKeys != null) { generateJDOFilterOverPartitions(conf, params, filterBuilder, partitionKeys); } else { @@ -283,6 +348,11 @@ public void generateJDOFilter(Configuration conf, Map params, } } + @Override + protected boolean shouldStop() { + return filterBuilder.hasError(); + } + //can only support "=" and "!=" for now, because our JDO lib is buggy when // using objects from map.get() private static final Set TABLE_FILTER_OPS = Sets.newHashSet( @@ -360,7 +430,7 @@ private void generateJDOFilterGeneral(Map params, private void generateJDOFilterOverPartitions(Configuration conf, Map params, FilterBuilder filterBuilder, List partitionKeys) throws MetaException { int partitionColumnCount = partitionKeys.size(); - int partitionColumnIndex = getPartColIndexForFilter(partitionKeys, filterBuilder); + int partitionColumnIndex = LeafNode.getPartColIndexForFilter(keyName, partitionKeys, filterBuilder); if (filterBuilder.hasError()) return; boolean canPushDownIntegral = @@ -434,32 +504,6 @@ public boolean canJdoUseStringsWithIntegral() { || (operator == Operator.NOTEQUALS2); } - /** - * Get partition column index in the table partition column list that - * corresponds to the key that is being filtered on by this tree node. - * @param partitionKeys list of partition keys. - * @param filterBuilder filter builder used to report error, if any. - * @return The index. - */ - public int getPartColIndexForFilter( - List partitionKeys, FilterBuilder filterBuilder) throws MetaException { - assert (partitionKeys.size() > 0); - int partitionColumnIndex; - for (partitionColumnIndex = 0; partitionColumnIndex < partitionKeys.size(); - ++partitionColumnIndex) { - if (partitionKeys.get(partitionColumnIndex).getName().equalsIgnoreCase(keyName)) { - break; - } - } - if( partitionColumnIndex == partitionKeys.size()) { - filterBuilder.setError("Specified key <" + keyName + - "> is not a partitioning key for the table"); - return -1; - } - - return partitionColumnIndex; - } - /** * Validates and gets the query parameter for JDO filter pushdown based on the column * and the constant stored in this node. @@ -499,16 +543,6 @@ private String getJdoFilterPushdownParam(int partColIndex, return isStringValue ? (String)val : Long.toString((Long)val); } - - @Override - public String toString() { - return "LeafNode{" + - "keyName='" + keyName + '\'' + - ", operator='" + operator + '\'' + - ", value=" + value + - (isReverseOrder ? ", isReverseOrder=true" : "") + - '}'; - } } public void accept(TreeVisitor treeVisitor) throws MetaException { @@ -618,21 +652,4 @@ public void addLeafNode(LeafNode newNode) { nodeStack.push(newNode); } - /** Generate the JDOQL filter for the given expression tree - * @param params the input map which is updated with the - * the parameterized values. Keys are the parameter names and values - * are the parameter values - * @param filterBuilder the filter builder to append to. - * @param partitionKeys - */ - public void generateJDOFilterFragment(Configuration conf, - Map params, FilterBuilder filterBuilder, List partitionKeys) throws MetaException { - if (root == null) { - return; - } - - filterBuilder.append(" && ( "); - root.generateJDOFilter(conf, params, filterBuilder, partitionKeys); - filterBuilder.append(" )"); - } } diff --git a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/parser/PartFilterVisitor.java b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/parser/PartFilterVisitor.java index 5d68d593c838..1ce0b27eabad 100644 --- a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/parser/PartFilterVisitor.java +++ b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/parser/PartFilterVisitor.java @@ -17,8 +17,6 @@ */ package org.apache.hadoop.hive.metastore.parser; -import java.sql.Date; -import java.sql.Timestamp; import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.List; @@ -231,25 +229,27 @@ public Long visitIntegerLiteral(PartitionFilterParser.IntegerLiteralContext ctx) } @Override - public Date visitDateLiteral(PartitionFilterParser.DateLiteralContext ctx) { + public String visitDateLiteral(PartitionFilterParser.DateLiteralContext ctx) { PartitionFilterParser.DateContext date = ctx.date(); String dateValue = unquoteString(date.value.getText()); try { - return MetaStoreUtils.convertStringToDate(dateValue); + MetaStoreUtils.convertStringToDate(dateValue); } catch (DateTimeParseException e) { throw new ParseCancellationException(e.getMessage()); } + return dateValue; } @Override - public Timestamp visitTimestampLiteral(PartitionFilterParser.TimestampLiteralContext ctx) { + public String visitTimestampLiteral(PartitionFilterParser.TimestampLiteralContext ctx) { PartitionFilterParser.TimestampContext timestamp = ctx.timestamp(); String timestampValue = unquoteString(timestamp.value.getText()); try { - return MetaStoreUtils.convertStringToTimestamp(timestampValue); + MetaStoreUtils.convertStringToTimestamp(timestampValue); } catch (DateTimeParseException e) { throw new ParseCancellationException(e.getMessage()); } + return timestampValue; } @Override diff --git a/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestPartFilterExprUtil.java b/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestPartFilterExprUtil.java index df1666ae5306..f4a7cfd58dac 100644 --- a/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestPartFilterExprUtil.java +++ b/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestPartFilterExprUtil.java @@ -104,25 +104,25 @@ public void testMultiColInExpressionWhenDateLiteralTypeIsSpecified() throws Meta @Test public void testSingleColInExpressionWhenTimestampLiteralTypeIsNotSpecifiedNorQuoted() throws MetaException { checkFilter("(dt) IN (2000-01-01 01:00:00, 2000-01-01 01:42:00)", - "TreeNode{lhs=LeafNode{keyName='dt', operator='=', value=2000-01-01 01:00:00.0}, andOr='OR', rhs=LeafNode{keyName='dt', operator='=', value=2000-01-01 01:42:00.0}}"); + "TreeNode{lhs=LeafNode{keyName='dt', operator='=', value=2000-01-01 01:00:00}, andOr='OR', rhs=LeafNode{keyName='dt', operator='=', value=2000-01-01 01:42:00}}"); } @Test public void testSingleColInExpressionWhenTimestampLiteralTypeIsSpecified() throws MetaException { checkFilter("(j) IN (TIMESTAMP'2000-01-01 01:00:00', TIMESTAMP'2000-01-01 01:42:00')", - "TreeNode{lhs=LeafNode{keyName='j', operator='=', value=2000-01-01 01:00:00.0}, andOr='OR', rhs=LeafNode{keyName='j', operator='=', value=2000-01-01 01:42:00.0}}"); + "TreeNode{lhs=LeafNode{keyName='j', operator='=', value=2000-01-01 01:00:00}, andOr='OR', rhs=LeafNode{keyName='j', operator='=', value=2000-01-01 01:42:00}}"); } @Test public void testMultiColInExpressionWhenTimestampLiteralTypeIsNotSpecifiedNorQuoted() throws MetaException { checkFilter("(struct(ds1,ds2)) IN (struct(2000-05-08 01:00:00, 2001-04-08 01:00:00), struct(2000-05-09 01:00:00, 2001-04-09 01:00:00))", - "TreeNode{lhs=TreeNode{lhs=LeafNode{keyName='ds1', operator='=', value=2000-05-08 01:00:00.0}, andOr='AND', rhs=LeafNode{keyName='ds2', operator='=', value=2001-04-08 01:00:00.0}}, andOr='OR', rhs=TreeNode{lhs=LeafNode{keyName='ds1', operator='=', value=2000-05-09 01:00:00.0}, andOr='AND', rhs=LeafNode{keyName='ds2', operator='=', value=2001-04-09 01:00:00.0}}}"); + "TreeNode{lhs=TreeNode{lhs=LeafNode{keyName='ds1', operator='=', value=2000-05-08 01:00:00}, andOr='AND', rhs=LeafNode{keyName='ds2', operator='=', value=2001-04-08 01:00:00}}, andOr='OR', rhs=TreeNode{lhs=LeafNode{keyName='ds1', operator='=', value=2000-05-09 01:00:00}, andOr='AND', rhs=LeafNode{keyName='ds2', operator='=', value=2001-04-09 01:00:00}}}"); } @Test public void testMultiColInExpressionWhenTimestampLiteralTypeIsSpecified() throws MetaException { checkFilter("(struct(ds1,ds2)) IN (struct(TIMESTAMP'2000-05-08 01:00:00',TIMESTAMP'2001-04-08 01:00:00'), struct(TIMESTAMP'2000-05-09 01:00:00',TIMESTAMP'2001-04-09 01:00:00'))", - "TreeNode{lhs=TreeNode{lhs=LeafNode{keyName='ds1', operator='=', value=2000-05-08 01:00:00.0}, andOr='AND', rhs=LeafNode{keyName='ds2', operator='=', value=2001-04-08 01:00:00.0}}, andOr='OR', rhs=TreeNode{lhs=LeafNode{keyName='ds1', operator='=', value=2000-05-09 01:00:00.0}, andOr='AND', rhs=LeafNode{keyName='ds2', operator='=', value=2001-04-09 01:00:00.0}}}"); + "TreeNode{lhs=TreeNode{lhs=LeafNode{keyName='ds1', operator='=', value=2000-05-08 01:00:00}, andOr='AND', rhs=LeafNode{keyName='ds2', operator='=', value=2001-04-08 01:00:00}}, andOr='OR', rhs=TreeNode{lhs=LeafNode{keyName='ds1', operator='=', value=2000-05-09 01:00:00}, andOr='AND', rhs=LeafNode{keyName='ds2', operator='=', value=2001-04-09 01:00:00}}}"); } @Test @@ -140,13 +140,13 @@ public void testBetweenExpressionWhenDateLiteralTypeIsSpecified() throws MetaExc @Test public void testBetweenExpressionWhenTimestampLiteralTypeIsNotSpecifiedNorQuoted() throws MetaException { checkFilter("dt BETWEEN 2000-01-01 01:00:00 AND 2000-01-01 01:42:00)", - "TreeNode{lhs=LeafNode{keyName='dt', operator='>=', value=2000-01-01 01:00:00.0}, andOr='AND', rhs=LeafNode{keyName='dt', operator='<=', value=2000-01-01 01:42:00.0}}"); + "TreeNode{lhs=LeafNode{keyName='dt', operator='>=', value=2000-01-01 01:00:00}, andOr='AND', rhs=LeafNode{keyName='dt', operator='<=', value=2000-01-01 01:42:00}}"); } @Test public void testBetweenExpressionWhenTimestampLiteralTypeIsSpecified() throws MetaException { checkFilter("dt BETWEEN TIMESTAMP'2000-01-01 01:00:00' AND TIMESTAMP'2000-01-01 01:42:00')", - "TreeNode{lhs=LeafNode{keyName='dt', operator='>=', value=2000-01-01 01:00:00.0}, andOr='AND', rhs=LeafNode{keyName='dt', operator='<=', value=2000-01-01 01:42:00.0}}"); + "TreeNode{lhs=LeafNode{keyName='dt', operator='>=', value=2000-01-01 01:00:00}, andOr='AND', rhs=LeafNode{keyName='dt', operator='<=', value=2000-01-01 01:42:00}}"); } @Test @@ -164,13 +164,13 @@ public void testBinaryExpressionWhenDateLiteralTypeIsSpecified() throws MetaExce @Test public void testBinaryExpressionWhenTimeStampLiteralTypeIsNotSpecifiedNorQuoted() throws MetaException { checkFilter("(j = 1990-11-10 01:00:00 or j = 1990-11-11 01:00:24 and j = 1990-11-12 01:42:00)", - "TreeNode{lhs=LeafNode{keyName='j', operator='=', value=1990-11-10 01:00:00.0}, andOr='OR', rhs=TreeNode{lhs=LeafNode{keyName='j', operator='=', value=1990-11-11 01:00:24.0}, andOr='AND', rhs=LeafNode{keyName='j', operator='=', value=1990-11-12 01:42:00.0}}}"); + "TreeNode{lhs=LeafNode{keyName='j', operator='=', value=1990-11-10 01:00:00}, andOr='OR', rhs=TreeNode{lhs=LeafNode{keyName='j', operator='=', value=1990-11-11 01:00:24}, andOr='AND', rhs=LeafNode{keyName='j', operator='=', value=1990-11-12 01:42:00}}}"); } @Test public void testBinaryExpressionWhenTimeStampLiteralTypeIsSpecified() throws MetaException { checkFilter("(j = TIMESTAMP'1990-11-10 01:00:00' or j = TIMESTAMP'1990-11-11 01:00:24' and j = TIMESTAMP'1990-11-12 01:42:00')", - "TreeNode{lhs=LeafNode{keyName='j', operator='=', value=1990-11-10 01:00:00.0}, andOr='OR', rhs=TreeNode{lhs=LeafNode{keyName='j', operator='=', value=1990-11-11 01:00:24.0}, andOr='AND', rhs=LeafNode{keyName='j', operator='=', value=1990-11-12 01:42:00.0}}}"); + "TreeNode{lhs=LeafNode{keyName='j', operator='=', value=1990-11-10 01:00:00}, andOr='OR', rhs=TreeNode{lhs=LeafNode{keyName='j', operator='=', value=1990-11-11 01:00:24}, andOr='AND', rhs=LeafNode{keyName='j', operator='=', value=1990-11-12 01:42:00}}}"); }