You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by ta...@apache.org on 2018/02/23 00:13:50 UTC

[3/3] impala git commit: IMPALA-5752: Add support for DECIMAL on Kudu tables

IMPALA-5752: Add support for DECIMAL on Kudu tables

Adds support for the Kudu DECIMAL type introduced in Kudu 1.7.0.

Note: Adding support for Kudu decimal min/max filters is
tracked in IMPALA-6533.

Tests:
* Added Kudu create with decimal test to AnalyzeDDLTest.java
* Added Kudu table_format to test_decimal_queries.py
** Both decimal.test and decimal-exprs.test workloads
* Added decimal queries to the following Kudu workloads:
** kudu_create.test
** kudu_delete.test
** kudu_insert.test
** kudu_update.test
** kudu_upsert.test

Change-Id: I3a9fe5acadc53ec198585d765a8cfb0abe56e199
Reviewed-on: http://gerrit.cloudera.org:8080/9368
Reviewed-by: Dimitris Tsirogiannis <dt...@cloudera.com>
Tested-by: Impala Public Jenkins


Project: http://git-wip-us.apache.org/repos/asf/impala/repo
Commit: http://git-wip-us.apache.org/repos/asf/impala/commit/0c8eba07
Tree: http://git-wip-us.apache.org/repos/asf/impala/tree/0c8eba07
Diff: http://git-wip-us.apache.org/repos/asf/impala/diff/0c8eba07

Branch: refs/heads/master
Commit: 0c8eba076c10eecde578917e7f8ef78bba983fc4
Parents: 5a1f432
Author: Grant Henke <gh...@cloudera.com>
Authored: Tue Feb 20 16:17:40 2018 -0600
Committer: Impala Public Jenkins <im...@gerrit.cloudera.org>
Committed: Fri Feb 23 00:03:54 2018 +0000

----------------------------------------------------------------------
 be/src/exec/kudu-scanner.cc                     |   6 +-
 be/src/exec/kudu-table-sink.cc                  |  10 +-
 be/src/exec/kudu-util.cc                        |  71 +++-
 be/src/exec/kudu-util.h                         |  27 +-
 be/src/exprs/kudu-partition-expr.cc             |   4 +-
 .../org/apache/impala/catalog/KuduColumn.java   |   2 +-
 .../org/apache/impala/planner/KuduScanNode.java |   3 +-
 .../impala/planner/RuntimeFilterGenerator.java  |   2 +
 .../impala/service/KuduCatalogOpExecutor.java   |  17 +-
 .../java/org/apache/impala/util/KuduUtil.java   |  43 +-
 .../apache/impala/analysis/AnalyzeDDLTest.java  |  19 +-
 .../functional/functional_schema_template.sql   |  31 ++
 .../datasets/functional/schema_constraints.csv  |   4 +
 .../queries/QueryTest/kudu_create.test          |  36 +-
 .../queries/QueryTest/kudu_delete.test          | 300 ++++++++------
 .../queries/QueryTest/kudu_describe.test        |  20 +
 .../queries/QueryTest/kudu_insert.test          | 255 ++++++------
 .../queries/QueryTest/kudu_update.test          | 270 +++++++------
 .../queries/QueryTest/kudu_upsert.test          | 392 ++++++++++---------
 tests/query_test/test_decimal_queries.py        |   4 +-
 tests/query_test/test_kudu.py                   |   3 +-
 21 files changed, 882 insertions(+), 637 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/be/src/exec/kudu-scanner.cc
----------------------------------------------------------------------
diff --git a/be/src/exec/kudu-scanner.cc b/be/src/exec/kudu-scanner.cc
index 909567c..3bc4441 100644
--- a/be/src/exec/kudu-scanner.cc
+++ b/be/src/exec/kudu-scanner.cc
@@ -185,7 +185,7 @@ Status KuduScanner::OpenNextScanToken(const string& scan_token, bool* eos) {
               ctx.filter->filter_desc().targets[it->second];
           const string& col_name = target_desc.kudu_col_name;
           DCHECK(col_name != "");
-          ColumnType col_type = ColumnType::FromThrift(target_desc.kudu_col_type);
+          const ColumnType& col_type = ColumnType::FromThrift(target_desc.kudu_col_type);
 
           void* min = filter->GetMin();
           void* max = filter->GetMax();
@@ -209,14 +209,14 @@ Status KuduScanner::OpenNextScanToken(const string& scan_token, bool* eos) {
           }
 
           KuduValue* min_value;
-          RETURN_IF_ERROR(CreateKuduValue(filter->type(), min, &min_value));
+          RETURN_IF_ERROR(CreateKuduValue(col_type, min, &min_value));
           KUDU_RETURN_IF_ERROR(
               scanner_->AddConjunctPredicate(scan_node_->table_->NewComparisonPredicate(
                   col_name, KuduPredicate::ComparisonOp::GREATER_EQUAL, min_value)),
               "Failed to add min predicate");
 
           KuduValue* max_value;
-          RETURN_IF_ERROR(CreateKuduValue(filter->type(), max, &max_value));
+          RETURN_IF_ERROR(CreateKuduValue(col_type, max, &max_value));
           KUDU_RETURN_IF_ERROR(
               scanner_->AddConjunctPredicate(scan_node_->table_->NewComparisonPredicate(
                   col_name, KuduPredicate::ComparisonOp::LESS_EQUAL, max_value)),

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/be/src/exec/kudu-table-sink.cc
----------------------------------------------------------------------
diff --git a/be/src/exec/kudu-table-sink.cc b/be/src/exec/kudu-table-sink.cc
index deb3b66..05f1d06 100644
--- a/be/src/exec/kudu-table-sink.cc
+++ b/be/src/exec/kudu-table-sink.cc
@@ -145,7 +145,9 @@ Status KuduTableSink::Open(RuntimeState* state) {
       return Status(strings::Substitute(
           "Table $0 has fewer columns than expected.", table_desc_->name()));
     }
-    ColumnType type = KuduDataTypeToColumnType(table_->schema().Column(col_idx).type());
+    const KuduColumnSchema& kudu_col = table_->schema().Column(col_idx);
+    const ColumnType& type =
+        KuduDataTypeToColumnType(kudu_col.type(), kudu_col.type_attributes());
     if (type != output_expr_evals_[i]->root().type()) {
       return Status(strings::Substitute("Column $0 has unexpected type. ($1 vs. $2)",
           table_->schema().Column(col_idx).name(), type.DebugString(),
@@ -256,13 +258,13 @@ Status KuduTableSink::Send(RuntimeState* state, RowBatch* batch) {
         }
       }
 
-      PrimitiveType type = output_expr_evals_[j]->root().type().type;
+      const ColumnType& type = output_expr_evals_[j]->root().type();
       Status s = WriteKuduValue(col, type, value, true, write->mutable_row());
       // This can only fail if we set a col to an incorrect type, which would be a bug in
       // planning, so we can DCHECK.
       DCHECK(s.ok()) << "WriteKuduValue failed for col = "
-                     << table_schema.Column(col).name() << " and type = "
-                     << output_expr_evals_[j]->root().type() << ": " << s.GetDetail();
+                     << table_schema.Column(col).name() << " and type = " << type << ": "
+                     << s.GetDetail();
       RETURN_IF_ERROR(s);
     }
     if (add_row) write_ops.push_back(move(write));

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/be/src/exec/kudu-util.cc
----------------------------------------------------------------------
diff --git a/be/src/exec/kudu-util.cc b/be/src/exec/kudu-util.cc
index d32df25..0538a61 100644
--- a/be/src/exec/kudu-util.cc
+++ b/be/src/exec/kudu-util.cc
@@ -28,6 +28,7 @@
 #include "common/logging.h"
 #include "common/names.h"
 #include "common/status.h"
+#include "runtime/decimal-value.h"
 #include "runtime/timestamp-value.h"
 #include "runtime/timestamp-value.inline.h"
 
@@ -35,6 +36,7 @@ using kudu::client::KuduSchema;
 using kudu::client::KuduClient;
 using kudu::client::KuduClientBuilder;
 using kudu::client::KuduColumnSchema;
+using kudu::client::KuduColumnTypeAttributes;
 using kudu::client::KuduValue;
 using DataType = kudu::client::KuduColumnSchema::DataType;
 
@@ -71,15 +73,6 @@ Status CreateKuduClient(const vector<string>& master_addrs,
   return Status::OK();
 }
 
-string KuduSchemaDebugString(const KuduSchema& schema) {
-  stringstream ss;
-  for (int i = 0; i < schema.num_columns(); ++i) {
-    const KuduColumnSchema& col = schema.Column(i);
-    ss << col.name() << " " << KuduColumnSchema::DataTypeToString(col.type()) << "\n";
-  }
-  return ss.str();
-}
-
 void LogKuduMessage(void* unused, kudu::client::KuduLogSeverity severity,
     const char* filename, int line_number, const struct ::tm* time, const char* message,
     size_t message_len) {
@@ -123,9 +116,10 @@ static Status ConvertTimestampValue(const TimestampValue* tv, int64_t* ts_micros
   return Status::OK();
 }
 
-Status WriteKuduValue(int col, PrimitiveType type, const void* value,
+Status WriteKuduValue(int col, const ColumnType& col_type, const void* value,
     bool copy_strings, kudu::KuduPartialRow* row) {
-  // TODO: codegen this to eliminate braching on type.
+  // TODO: codegen this to eliminate branching on type.
+  PrimitiveType type = col_type.type;
   switch (type) {
     case TYPE_VARCHAR:
     case TYPE_STRING: {
@@ -172,7 +166,31 @@ Status WriteKuduValue(int col, PrimitiveType type, const void* value,
       RETURN_IF_ERROR(ConvertTimestampValue(
           reinterpret_cast<const TimestampValue*>(value), &ts_micros));
       KUDU_RETURN_IF_ERROR(
-          row->SetUnixTimeMicros(col, ts_micros), "Could not add Kudu WriteOp.");
+          row->SetUnixTimeMicros(col, ts_micros), "Could not set Kudu row value.");
+      break;
+    case TYPE_DECIMAL:
+      switch (col_type.GetByteSize()) {
+        case 4:
+          KUDU_RETURN_IF_ERROR(
+              row->SetUnscaledDecimal(
+                  col, reinterpret_cast<const Decimal4Value*>(value)->value()),
+              "Could not set Kudu row value.");
+          break;
+        case 8:
+          KUDU_RETURN_IF_ERROR(
+              row->SetUnscaledDecimal(
+                  col, reinterpret_cast<const Decimal8Value*>(value)->value()),
+              "Could not set Kudu row value.");
+          break;
+        case 16:
+          KUDU_RETURN_IF_ERROR(
+              row->SetUnscaledDecimal(
+                  col, reinterpret_cast<const Decimal16Value*>(value)->value()),
+              "Could not set Kudu row value.");
+          break;
+        default:
+          DCHECK(false) << "Unknown decimal byte size: " << col_type.GetByteSize();
+      }
       break;
     default:
       return Status(TErrorCode::IMPALA_KUDU_TYPE_MISSING, TypeToString(type));
@@ -181,7 +199,8 @@ Status WriteKuduValue(int col, PrimitiveType type, const void* value,
   return Status::OK();
 }
 
-ColumnType KuduDataTypeToColumnType(DataType type) {
+ColumnType KuduDataTypeToColumnType(
+    DataType type, const KuduColumnTypeAttributes& type_attributes) {
   switch (type) {
     case DataType::INT8: return ColumnType(PrimitiveType::TYPE_TINYINT);
     case DataType::INT16: return ColumnType(PrimitiveType::TYPE_SMALLINT);
@@ -194,13 +213,14 @@ ColumnType KuduDataTypeToColumnType(DataType type) {
     case DataType::BINARY: return ColumnType(PrimitiveType::TYPE_BINARY);
     case DataType::UNIXTIME_MICROS: return ColumnType(PrimitiveType::TYPE_TIMESTAMP);
     case DataType::DECIMAL:
-      DCHECK(false) << "DECIMAL is not supported on Kudu.";
-      return ColumnType(PrimitiveType::INVALID_TYPE);
+      return ColumnType::CreateDecimalType(
+          type_attributes.precision(), type_attributes.scale());
   }
   return ColumnType(PrimitiveType::INVALID_TYPE);
 }
 
-Status CreateKuduValue(PrimitiveType type, void* value, KuduValue** out) {
+Status CreateKuduValue(const ColumnType& col_type, void* value, KuduValue** out) {
+  PrimitiveType type = col_type.type;
   switch (type) {
     case TYPE_VARCHAR:
     case TYPE_STRING: {
@@ -237,6 +257,25 @@ Status CreateKuduValue(PrimitiveType type, void* value, KuduValue** out) {
       *out = KuduValue::FromInt(ts_micros);
       break;
     }
+    case TYPE_DECIMAL: {
+      switch (col_type.GetByteSize()) {
+        case 4:
+          *out = KuduValue::FromDecimal(
+              reinterpret_cast<const Decimal4Value*>(value)->value(), col_type.scale);
+          break;
+        case 8:
+          *out = KuduValue::FromDecimal(
+              reinterpret_cast<const Decimal8Value*>(value)->value(), col_type.scale);
+          break;
+        case 16:
+          *out = KuduValue::FromDecimal(
+              reinterpret_cast<const Decimal16Value*>(value)->value(), col_type.scale);
+          break;
+        default:
+          DCHECK(false) << "Unknown decimal byte size: " << col_type.GetByteSize();
+      }
+      break;
+    }
     default:
       return Status(TErrorCode::IMPALA_KUDU_TYPE_MISSING, TypeToString(type));
   }

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/be/src/exec/kudu-util.h
----------------------------------------------------------------------
diff --git a/be/src/exec/kudu-util.h b/be/src/exec/kudu-util.h
index 5fd1140..36764d4 100644
--- a/be/src/exec/kudu-util.h
+++ b/be/src/exec/kudu-util.h
@@ -65,9 +65,6 @@ bool KuduIsAvailable();
 Status CreateKuduClient(const std::vector<std::string>& master_addrs,
     kudu::client::sp::shared_ptr<kudu::client::KuduClient>* client) WARN_UNUSED_RESULT;
 
-/// Returns a debug string for the KuduSchema.
-std::string KuduSchemaDebugString(const kudu::client::KuduSchema& schema);
-
 /// Initializes Kudu's logging by binding a callback that logs back to Impala's glog. This
 /// also sets Kudu's verbose logging to whatever level is set in Impala.
 void InitKuduLogging();
@@ -78,20 +75,22 @@ void InitKuduLogging();
 void LogKuduMessage(kudu::client::KuduLogSeverity severity, const char* filename,
     int line_number, const struct ::tm* time, const char* message, size_t message_len);
 
-/// Casts 'value' according to 'type' and writes it into 'row' at position 'col'.
-/// If 'type' is STRING or VARCHAR, 'copy_strings' determines if 'value' will be copied
-/// into memory owned by the row. If false, string data must remain valid while the row
-/// is being used.
-Status WriteKuduValue(int col, PrimitiveType type, const void* value,
+/// Casts 'value' according to the column type in 'col_type' and writes it into 'row'
+/// at position 'col'. If the column type's primitive type is STRING or VARCHAR,
+/// 'copy_strings' determines if 'value' will be copied into memory owned by the row.
+/// If false, string data must remain valid while the row is being used.
+Status WriteKuduValue(int col, const ColumnType& col_type, const void* value,
     bool copy_strings, kudu::KuduPartialRow* row) WARN_UNUSED_RESULT;
 
-/// Casts 'value' according to 'type' and create a new KuduValue containing 'value' which
-/// is returned in 'out'.
-Status CreateKuduValue(
-    PrimitiveType type, void* value, kudu::client::KuduValue** out) WARN_UNUSED_RESULT;
+/// Casts 'value' according to the column type in 'col_type' and create a
+/// new KuduValue containing 'value' which is returned in 'out'.
+Status CreateKuduValue(const ColumnType& col_type, void* value,
+    kudu::client::KuduValue** out) WARN_UNUSED_RESULT;
 
-/// Takes a Kudu client DataType and returns the corresponding Impala ColumnType.
-ColumnType KuduDataTypeToColumnType(kudu::client::KuduColumnSchema::DataType type);
+/// Takes a Kudu client DataType and KuduColumnTypeAttributes and
+/// returns the corresponding Impala ColumnType.
+ColumnType KuduDataTypeToColumnType(kudu::client::KuduColumnSchema::DataType type,
+    const kudu::client::KuduColumnTypeAttributes& type_attributes);
 
 /// Utility function for creating an Impala Status object based on a kudu::Status object.
 /// 'k_status' is the kudu::Status object.

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/be/src/exprs/kudu-partition-expr.cc
----------------------------------------------------------------------
diff --git a/be/src/exprs/kudu-partition-expr.cc b/be/src/exprs/kudu-partition-expr.cc
index 2cc96f0..ce38e24 100644
--- a/be/src/exprs/kudu-partition-expr.cc
+++ b/be/src/exprs/kudu-partition-expr.cc
@@ -70,8 +70,8 @@ IntVal KuduPartitionExpr::GetIntVal(ScalarExprEvaluator* eval,
     }
     int col = tkudu_partition_expr_.referenced_columns[i];
     const ColumnDescriptor& col_desc = table_desc_->col_descs()[col];
-    PrimitiveType type = col_desc.type().type;
-    DCHECK_EQ(GetChild(i)->type().type, type);
+    const ColumnType& type = col_desc.type();
+    DCHECK_EQ(GetChild(i)->type().type, type.type);
     Status s = WriteKuduValue(col, type, val, false, row_.get());
     // This can only fail if we set a col to an incorect type, which would be a bug in
     // planning, so we can DCHECK.

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/fe/src/main/java/org/apache/impala/catalog/KuduColumn.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/catalog/KuduColumn.java b/fe/src/main/java/org/apache/impala/catalog/KuduColumn.java
index 2dd3e85..a4b8e5f 100644
--- a/fe/src/main/java/org/apache/impala/catalog/KuduColumn.java
+++ b/fe/src/main/java/org/apache/impala/catalog/KuduColumn.java
@@ -72,7 +72,7 @@ public class KuduColumn extends Column {
 
   public static KuduColumn fromColumnSchema(ColumnSchema colSchema, int position)
       throws ImpalaRuntimeException {
-    Type type = KuduUtil.toImpalaType(colSchema.getType());
+    Type type = KuduUtil.toImpalaType(colSchema.getType(), colSchema.getTypeAttributes());
     Object defaultValue = colSchema.getDefaultValue();
     LiteralExpr defaultValueExpr = null;
     if (defaultValue != null) {

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/fe/src/main/java/org/apache/impala/planner/KuduScanNode.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/planner/KuduScanNode.java b/fe/src/main/java/org/apache/impala/planner/KuduScanNode.java
index 390592e..a02b49b 100644
--- a/fe/src/main/java/org/apache/impala/planner/KuduScanNode.java
+++ b/fe/src/main/java/org/apache/impala/planner/KuduScanNode.java
@@ -162,7 +162,8 @@ public class KuduScanNode extends ScanNode {
             "outdated and need to be refreshed.");
       }
 
-      Type kuduColType = KuduUtil.toImpalaType(kuduCol.getType());
+      Type kuduColType =
+          KuduUtil.toImpalaType(kuduCol.getType(), kuduCol.getTypeAttributes());
       if (!colType.equals(kuduColType)) {
         throw new ImpalaRuntimeException("Column '" + colName + "' is type " +
             kuduColType.toSql() + " but Impala expected " + colType.toSql() +

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/fe/src/main/java/org/apache/impala/planner/RuntimeFilterGenerator.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/planner/RuntimeFilterGenerator.java b/fe/src/main/java/org/apache/impala/planner/RuntimeFilterGenerator.java
index 5368b5f..89f14d1 100644
--- a/fe/src/main/java/org/apache/impala/planner/RuntimeFilterGenerator.java
+++ b/fe/src/main/java/org/apache/impala/planner/RuntimeFilterGenerator.java
@@ -699,6 +699,8 @@ public final class RuntimeFilterGenerator {
         continue;
       } else if (scanNode instanceof KuduScanNode) {
         if (filter.getType() != TRuntimeFilterType.MIN_MAX) continue;
+        // TODO: IMPALA-6533: Support Kudu Decimal Min/Max Filters
+        if (targetExpr.getType().isDecimal()) continue;
         SlotRef slotRef = targetExpr.unwrapSlotRef(true);
         // Kudu only supports targeting a single column, not general exprs, so the target
         // must be a SlotRef pointing to a column. We can allow implicit integer casts

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/fe/src/main/java/org/apache/impala/service/KuduCatalogOpExecutor.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/service/KuduCatalogOpExecutor.java b/fe/src/main/java/org/apache/impala/service/KuduCatalogOpExecutor.java
index c81aca4..0ce0cf9 100644
--- a/fe/src/main/java/org/apache/impala/service/KuduCatalogOpExecutor.java
+++ b/fe/src/main/java/org/apache/impala/service/KuduCatalogOpExecutor.java
@@ -48,6 +48,7 @@ import org.apache.kudu.client.KuduClient;
 import org.apache.kudu.client.KuduException;
 import org.apache.kudu.client.PartialRow;
 import org.apache.kudu.client.RangePartitionBound;
+import org.apache.kudu.util.DecimalUtil;
 import org.apache.log4j.Logger;
 
 import com.google.common.base.Preconditions;
@@ -113,8 +114,8 @@ public class KuduCatalogOpExecutor {
       csb.nullable(!isKey);
     }
     if (column.isSetDefault_value()) {
-      csb.defaultValue(KuduUtil.getKuduDefaultValue(column.getDefault_value(), kuduType,
-            column.getColumnName()));
+      csb.defaultValue(KuduUtil.getKuduDefaultValue(
+          column.getDefault_value(), type, column.getColumnName()));
     }
     if (column.isSetBlock_size()) csb.desiredBlockSize(column.getBlock_size());
     if (column.isSetEncoding()) {
@@ -123,6 +124,10 @@ public class KuduCatalogOpExecutor {
     if (column.isSetCompression()) {
       csb.compressionAlgorithm(KuduUtil.fromThrift(column.getCompression()));
     }
+    if (type.isDecimal()) {
+      csb.typeAttributes(
+          DecimalUtil.typeAttributes(type.getPrecision(), type.getDecimalDigits()));
+    }
     return csb.build();
   }
 
@@ -267,7 +272,8 @@ public class KuduCatalogOpExecutor {
               "Error loading Kudu table: Impala does not support column names that " +
               "differ only in casing '%s'", colSchema.getName()));
         }
-        Type type = KuduUtil.toImpalaType(colSchema.getType());
+        Type type =
+            KuduUtil.toImpalaType(colSchema.getType(), colSchema.getTypeAttributes());
         cols.add(new FieldSchema(colSchema.getName(), type.toSql().toLowerCase(), null));
       }
     } catch (Exception e) {
@@ -446,10 +452,9 @@ public class KuduCatalogOpExecutor {
     AlterTableOptions alterTableOptions = new AlterTableOptions();
 
     if (newCol.isSetDefault_value()) {
-      org.apache.kudu.Type kuduType =
-          KuduUtil.fromImpalaType(Type.fromThrift(newCol.getColumnType()));
+      Type type = Type.fromThrift(newCol.getColumnType());
       Object defaultValue = KuduUtil.getKuduDefaultValue(
-          newCol.getDefault_value(), kuduType, newCol.getColumnName());
+          newCol.getDefault_value(), type, newCol.getColumnName());
       if (defaultValue == null) {
         alterTableOptions.removeDefault(kuduColName);
       } else {

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/fe/src/main/java/org/apache/impala/util/KuduUtil.java
----------------------------------------------------------------------
diff --git a/fe/src/main/java/org/apache/impala/util/KuduUtil.java b/fe/src/main/java/org/apache/impala/util/KuduUtil.java
index 4df8005..07378a9 100644
--- a/fe/src/main/java/org/apache/impala/util/KuduUtil.java
+++ b/fe/src/main/java/org/apache/impala/util/KuduUtil.java
@@ -19,6 +19,8 @@ package org.apache.impala.util;
 
 import static java.lang.String.format;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.util.List;
 import java.util.Map;
 
@@ -48,6 +50,7 @@ import org.apache.impala.thrift.THdfsCompression;
 import org.apache.kudu.ColumnSchema;
 import org.apache.kudu.ColumnSchema.CompressionAlgorithm;
 import org.apache.kudu.ColumnSchema.Encoding;
+import org.apache.kudu.ColumnTypeAttributes;
 import org.apache.kudu.Schema;
 import org.apache.kudu.client.KuduClient;
 import org.apache.kudu.client.KuduClient.KuduClientBuilder;
@@ -104,8 +107,7 @@ public class KuduUtil {
       String colName = rangePartitionColumns.get(i);
       ColumnSchema col = schema.getColumn(colName);
       Preconditions.checkNotNull(col);
-      setKey(col.getType(), boundaryValues.get(i), schema.getColumnIndex(colName),
-          colName, bound);
+      setKey(col, boundaryValues.get(i), schema.getColumnIndex(colName), bound);
     }
     return bound;
   }
@@ -140,10 +142,12 @@ public class KuduUtil {
    * Sets the value 'boundaryVal' in 'key' at 'pos'. Checks if 'boundaryVal' has the
    * expected data type.
    */
-  private static void setKey(org.apache.kudu.Type type, TExpr boundaryVal, int pos,
-      String colName, PartialRow key) throws ImpalaRuntimeException {
+  private static void setKey(ColumnSchema col, TExpr boundaryVal, int pos, PartialRow key)
+      throws ImpalaRuntimeException {
     Preconditions.checkState(boundaryVal.getNodes().size() == 1);
     TExprNode literal = boundaryVal.getNodes().get(0);
+    String colName = col.getName();
+    org.apache.kudu.Type type = col.getType();
     switch (type) {
       case INT8:
         checkCorrectType(literal.isSetInt_literal(), type, colName, literal);
@@ -169,6 +173,12 @@ public class KuduUtil {
         checkCorrectType(literal.isSetInt_literal(), type, colName, literal);
         key.addLong(pos, literal.getInt_literal().getValue());
         break;
+      case DECIMAL:
+        checkCorrectType(literal.isSetDecimal_literal(), type, colName, literal);
+        BigInteger unscaledVal = new BigInteger(literal.getDecimal_literal().getValue());
+        int scale = col.getTypeAttributes().getScale();
+        key.addDecimal(pos, new BigDecimal(unscaledVal, scale));
+        break;
       default:
         throw new ImpalaRuntimeException("Key columns not supported for type: "
             + type.toString());
@@ -177,15 +187,17 @@ public class KuduUtil {
 
   /**
    * Returns the actual value of the specified defaultValue literal. The returned type is
-   * the value type stored by Kudu for the column. E.g. if 'type' is 'INT8', the returned
-   * value is a Java byte, and if 'type' is 'UNIXTIME_MICROS', the returned value is
+   * the value type stored by Kudu for the column. For example, The `impalaType` is
+   * translated to a Kudu Type 'type' and if 'type' is 'INT8', the returned
+   * value is a Java byte, or if 'type' is 'UNIXTIME_MICROS', the returned value is
    * a Java long.
    */
-  public static Object getKuduDefaultValue(TExpr defaultValue,
-      org.apache.kudu.Type type, String colName) throws ImpalaRuntimeException {
+  public static Object getKuduDefaultValue(
+      TExpr defaultValue, Type impalaType, String colName) throws ImpalaRuntimeException {
     Preconditions.checkState(defaultValue.getNodes().size() == 1);
     TExprNode literal = defaultValue.getNodes().get(0);
     if (literal.getNode_type() == TExprNodeType.NULL_LITERAL) return null;
+    org.apache.kudu.Type type = KuduUtil.fromImpalaType(impalaType);
     switch (type) {
       case INT8:
         checkCorrectType(literal.isSetInt_literal(), type, colName, literal);
@@ -214,6 +226,10 @@ public class KuduUtil {
       case UNIXTIME_MICROS:
         checkCorrectType(literal.isSetInt_literal(), type, colName, literal);
         return literal.getInt_literal().getValue();
+      case DECIMAL:
+        checkCorrectType(literal.isSetDecimal_literal(), type, colName, literal);
+        BigInteger unscaledVal = new BigInteger(literal.getDecimal_literal().getValue());
+        return new BigDecimal(unscaledVal, impalaType.getDecimalDigits());
       default:
         throw new ImpalaRuntimeException("Unsupported value for column type: " +
             type.toString());
@@ -392,13 +408,13 @@ public class KuduUtil {
       case DOUBLE: return org.apache.kudu.Type.DOUBLE;
       case FLOAT: return org.apache.kudu.Type.FLOAT;
       case TIMESTAMP: return org.apache.kudu.Type.UNIXTIME_MICROS;
-        /* Fall through below */
+      case DECIMAL: return org.apache.kudu.Type.DECIMAL;
+      /* Fall through below */
       case INVALID_TYPE:
       case NULL_TYPE:
       case BINARY:
       case DATE:
       case DATETIME:
-      case DECIMAL:
       case CHAR:
       case VARCHAR:
       default:
@@ -407,8 +423,8 @@ public class KuduUtil {
     }
   }
 
-  public static Type toImpalaType(org.apache.kudu.Type t)
-      throws ImpalaRuntimeException {
+  public static Type toImpalaType(org.apache.kudu.Type t,
+      ColumnTypeAttributes typeAttributes) throws ImpalaRuntimeException {
     switch (t) {
       case BOOL: return Type.BOOLEAN;
       case DOUBLE: return Type.DOUBLE;
@@ -419,6 +435,9 @@ public class KuduUtil {
       case INT64: return Type.BIGINT;
       case STRING: return Type.STRING;
       case UNIXTIME_MICROS: return Type.TIMESTAMP;
+      case DECIMAL:
+        return ScalarType.createDecimalType(
+            typeAttributes.getPrecision(), typeAttributes.getScale());
       default:
         throw new ImpalaRuntimeException(String.format(
             "Kudu type '%s' is not supported in Impala", t.getName()));

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java
----------------------------------------------------------------------
diff --git a/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java b/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java
index 56f81e3..ce49828 100644
--- a/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java
+++ b/fe/src/test/java/org/apache/impala/analysis/AnalyzeDDLTest.java
@@ -1792,6 +1792,10 @@ public class AnalyzeDDLTest extends FrontendTestBase {
         "left join functional.alltypes b " +
         "on b.timestamp_col between a.timestamp_col and a.timestamp_col) " +
         "select a.timestamp_col, a.year from tmp a");
+    // CTAS into Kudu with decimal type
+    AnalyzesOk("create table t primary key (id) partition by hash partitions 3" +
+        " stored as kudu as select c1 as id from functional.decimal_tiny");
+
     // CTAS in an external Kudu table
     AnalysisError("create external table t stored as kudu " +
         "tblproperties('kudu.table_name'='t') as select id, int_col from " +
@@ -1806,9 +1810,6 @@ public class AnalyzeDDLTest extends FrontendTestBase {
         " stored as kudu as select vc from functional.chars_tiny",
         "Cannot create table 't': Type VARCHAR(32) is not supported in Kudu");
     AnalysisError("create table t primary key (id) partition by hash partitions 3" +
-        " stored as kudu as select c1 as id from functional.decimal_tiny",
-        "Cannot create table 't': Type DECIMAL(10,4) is not supported in Kudu");
-    AnalysisError("create table t primary key (id) partition by hash partitions 3" +
         " stored as kudu as select id, s from functional.complextypes_fileformat",
         "Expr 's' in select list returns a complex type 'STRUCT<f1:STRING,f2:INT>'.\n" +
         "Only scalar types are allowed in the select list.");
@@ -2212,6 +2213,9 @@ public class AnalyzeDDLTest extends FrontendTestBase {
     AnalyzesOk("alter table functional_kudu.testtbl add columns (a1 tinyint null, a2 " +
         "smallint null, a3 int null, a4 bigint null, a5 string null, a6 float null, " +
         "a7 double null, a8 boolean null comment 'boolean')");
+    // Decimal types
+    AnalyzesOk("alter table functional_kudu.testtbl add columns (d1 decimal null, d2 " +
+        "decimal(9, 2) null, d3 decimal(15, 15) null, d4 decimal(38, 0) null)");
     // Complex types
     AnalysisError("alter table functional_kudu.testtbl add columns ( "+
         "a struct<f1:int>)", "Kudu tables do not support complex types: " +
@@ -2225,6 +2229,8 @@ public class AnalyzeDDLTest extends FrontendTestBase {
         "default 10)");
     AnalyzesOk("alter table functional_kudu.testtbl add columns (a1 int null " +
         "default 10)");
+    AnalyzesOk("alter table functional_kudu.testtbl add columns (d1 decimal(9, 2) null " +
+        "default 99.99)");
     // Other Kudu column options
     AnalyzesOk("alter table functional_kudu.testtbl add columns (a int encoding rle)");
     AnalyzesOk("alter table functional_kudu.testtbl add columns (a int compression lz4)");
@@ -2477,8 +2483,7 @@ public class AnalyzeDDLTest extends FrontendTestBase {
         "in Kudu tables.");
 
     // Test unsupported Kudu types
-    List<String> unsupportedTypes = Lists.newArrayList(
-        "DECIMAL(9,0)", "VARCHAR(20)", "CHAR(20)",
+    List<String> unsupportedTypes = Lists.newArrayList("VARCHAR(20)", "CHAR(20)",
         "STRUCT<f1:INT,f2:STRING>", "ARRAY<INT>", "MAP<STRING,STRING>");
     for (String t: unsupportedTypes) {
       String expectedError = String.format(
@@ -2529,7 +2534,8 @@ public class AnalyzeDDLTest extends FrontendTestBase {
     AnalyzesOk("create table tab (x int primary key, i1 tinyint default null, " +
         "i2 smallint default null, i3 int default null, i4 bigint default null, " +
         "vals string default null, valf float default null, vald double default null, " +
-        "valb boolean default null) partition by hash (x) partitions 3 stored as kudu");
+        "valb boolean default null, valdec decimal(10, 5) default null) " +
+        "partition by hash (x) partitions 3 stored as kudu");
     // Use NULL as a default value on a non-nullable column
     AnalysisError("create table tab (x int primary key, y int not null default null) " +
         "partition by hash (x) partitions 3 stored as kudu", "Default value of NULL " +
@@ -2561,6 +2567,7 @@ public class AnalyzeDDLTest extends FrontendTestBase {
         "i3 int default 100, i4 bigint default 1000, vals string default 'test', " +
         "valf float default cast(1.2 as float), vald double default " +
         "cast(3.1452 as double), valb boolean default true, " +
+        "valdec decimal(10, 5) default 3.14159, " +
         "primary key (i1, i2, i3, i4, vals)) partition by hash (i1) partitions 3 " +
         "stored as kudu");
     AnalyzesOk("create table tab (i int primary key default 1+1+1) " +

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/testdata/datasets/functional/functional_schema_template.sql
----------------------------------------------------------------------
diff --git a/testdata/datasets/functional/functional_schema_template.sql b/testdata/datasets/functional/functional_schema_template.sql
index f4b6b34..8db806a 100644
--- a/testdata/datasets/functional/functional_schema_template.sql
+++ b/testdata/datasets/functional/functional_schema_template.sql
@@ -1726,6 +1726,23 @@ ${IMPALA_HOME}/testdata/data/decimal_tbl.txt /test-warehouse/decimal_tbl/d6=1/
 ---- DEPENDENT_LOAD
 INSERT OVERWRITE TABLE {db_name}{db_suffix}.{table_name} partition(d6)
 select * from functional.{table_name};
+---- CREATE_KUDU
+DROP TABLE IF EXISTS {db_name}{db_suffix}.{table_name};
+CREATE TABLE {db_name}{db_suffix}.{table_name} (
+  d1 DECIMAL,
+  d2 DECIMAL(10, 0),
+  d3 DECIMAL(20, 10),
+  d4 DECIMAL(38, 38),
+  d5 DECIMAL(10, 5),
+  d6 DECIMAL(9, 0),
+  PRIMARY KEY (d1, d2, d3, d4, d5, d6)
+)
+PARTITION BY HASH PARTITIONS 3
+STORED AS KUDU;
+---- DEPENDENT_LOAD_KUDU
+INSERT into TABLE {db_name}{db_suffix}.{table_name}
+SELECT d1, d2, d3, d4, d5, d6
+FROM {db_name}.{table_name};
 ====
 ---- DATASET
 functional
@@ -1743,6 +1760,20 @@ ${IMPALA_HOME}/testdata/data/decimal-tiny.txt /test-warehouse/decimal_tiny/
 ---- DEPENDENT_LOAD
 INSERT OVERWRITE TABLE {db_name}{db_suffix}.{table_name}
 select * from functional.{table_name};
+---- CREATE_KUDU
+DROP TABLE IF EXISTS {db_name}{db_suffix}.{table_name};
+CREATE TABLE {db_name}{db_suffix}.{table_name} (
+  c1 DECIMAL(10, 4),
+  c2 DECIMAL(15, 5),
+  c3 DECIMAL(1, 1),
+  PRIMARY KEY (c1, c2, c3)
+)
+PARTITION BY HASH PARTITIONS 3
+STORED AS KUDU;
+---- DEPENDENT_LOAD_KUDU
+INSERT into TABLE {db_name}{db_suffix}.{table_name}
+SELECT c1, c2, c3
+FROM {db_name}.{table_name};
 ====
 ---- DATASET
 functional

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/testdata/datasets/functional/schema_constraints.csv
----------------------------------------------------------------------
diff --git a/testdata/datasets/functional/schema_constraints.csv b/testdata/datasets/functional/schema_constraints.csv
index 355e9b1..ef65b9a 100644
--- a/testdata/datasets/functional/schema_constraints.csv
+++ b/testdata/datasets/functional/schema_constraints.csv
@@ -132,6 +132,8 @@ table_name:decimal_tbl, constraint:restrict_to, table_format:text/none/none
 table_name:decimal_tiny, constraint:restrict_to, table_format:text/none/none
 table_name:decimal_tbl, constraint:restrict_to, table_format:parquet/none/none
 table_name:decimal_tiny, constraint:restrict_to, table_format:parquet/none/none
+table_name:decimal_tbl, constraint:restrict_to, table_format:kudu/none/none
+table_name:decimal_tiny, constraint:restrict_to, table_format:kudu/none/none
 
 table_name:avro_decimal_tbl, constraint:restrict_to, table_format:avro/snap/block
 
@@ -186,6 +188,8 @@ table_name:tinyinttable, constraint:only, table_format:kudu/none/none
 table_name:zipcode_incomes, constraint:only, table_format:kudu/none/none
 table_name:nulltable, constraint:only, table_format:kudu/none/none
 table_name:nullescapedtable, constraint:only, table_format:kudu/none/none
+table_name:decimal_tbl, constraint:only, table_format:kudu/none/none
+table_name:decimal_tiny, constraint:only, table_format:kudu/none/none
 
 # Skipping header lines is only effective with text tables
 table_name:table_with_header, constraint:restrict_to, table_format:text/none/none

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/testdata/workloads/functional-query/queries/QueryTest/kudu_create.test
----------------------------------------------------------------------
diff --git a/testdata/workloads/functional-query/queries/QueryTest/kudu_create.test b/testdata/workloads/functional-query/queries/QueryTest/kudu_create.test
index f6e16e1..24dfdf1 100644
--- a/testdata/workloads/functional-query/queries/QueryTest/kudu_create.test
+++ b/testdata/workloads/functional-query/queries/QueryTest/kudu_create.test
@@ -129,7 +129,9 @@ INT,STRING,FLOAT,BIGINT
 create table tbl_with_null_defaults (x int primary key, i1 tinyint default null,
   i2 smallint default null, i3 int default null, i4 bigint default null,
   vals string default null, valf float default null, vald double default null,
-  valb boolean default null) partition by hash (x) partitions 3 stored as kudu
+  valb boolean default null, valdec4 decimal(9) default null,
+  valdec8 decimal(18) default null, valdec16 decimal(38) default null)
+  partition by hash (x) partitions 3 stored as kudu
 ---- RESULTS
 ====
 ---- QUERY
@@ -138,11 +140,11 @@ insert into tbl_with_null_defaults (x) values (1);
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-X, I1, I2, I3, I4, VALS, VALF, VALD, VALB
+X, I1, I2, I3, I4, VALS, VALF, VALD, VALB, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tbl_with_null_defaults
-1,NULL,NULL,NULL,NULL,'NULL',NULL,NULL,NULL
+1,NULL,NULL,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL
 ---- TYPES
-INT,TINYINT,SMALLINT,INT,BIGINT,STRING,FLOAT,DOUBLE,BOOLEAN
+INT,TINYINT,SMALLINT,INT,BIGINT,STRING,FLOAT,DOUBLE,BOOLEAN,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # Overlapping ranges are rejected by the Kudu client
@@ -287,4 +289,30 @@ select * from unpartitioned_kudu_table2
 ID
 ---- TYPES
 INT
+====
+---- QUERY
+# Creates a Kudu table with decimal columns and primary key
+create table create_decimal
+(
+ decimal_4 decimal(9, 9),
+ decimal_8 decimal(18, 2) not null default 100.00,
+ decimal_16 decimal(38, 0) null,
+ primary key (decimal_4))
+stored as kudu;
+---- RESULTS
+====
+---- QUERY
+# Create as select table with decimal columns and primary key
+create table ctas_decimal primary key (d1,d2,d3)
+stored as kudu
+as select * from functional.decimal_tbl;
+select * from ctas_decimal;
+---- RESULTS
+1234,2222,1.2345678900,0.12345678900000000000000000000000000000,12345.78900,1
+2345,111,12.3456789000,0.12345678900000000000000000000000000000,3.14100,1
+12345,333,123.4567890000,0.12345678900000000000000000000000000000,11.22000,1
+12345,333,1234.5678900000,0.12345678900000000000000000000000000000,0.10000,1
+132842,333,12345.6789000000,0.12345678900000000000000000000000000000,0.77889,1
+---- TYPES
+DECIMAL,DECIMAL,DECIMAL,DECIMAL,DECIMAL,DECIMAL
 ====
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/testdata/workloads/functional-query/queries/QueryTest/kudu_delete.test
----------------------------------------------------------------------
diff --git a/testdata/workloads/functional-query/queries/QueryTest/kudu_delete.test b/testdata/workloads/functional-query/queries/QueryTest/kudu_delete.test
index 7094c59..3abcdab 100644
--- a/testdata/workloads/functional-query/queries/QueryTest/kudu_delete.test
+++ b/testdata/workloads/functional-query/queries/QueryTest/kudu_delete.test
@@ -2,23 +2,25 @@
 ---- QUERY
 create table tdata
   (id int primary key, valf float null, vali bigint null, valv string null,
-   valb boolean null, valt tinyint null, vals smallint null, vald double null)
+   valb boolean null, valt tinyint null, vals smallint null, vald double null,
+   valdec4 decimal(9,9) null, valdec8 decimal(18,2) null,
+   valdec16 decimal(38, 0) null)
   PARTITION BY RANGE (PARTITION VALUES < 100, PARTITION 100 <= VALUES < 1000,
   PARTITION 1000 <= VALUES <= 10000) STORED AS KUDU
 ---- RESULTS
 ====
 ---- QUERY
 insert into table tdata values
-(1, 1.0, 1, 'one', true, 1, 1, 1),
-(2, -2, 20, 'two', false, 0, 1, NULL),
-(3, 0, NULL, 'three', false, 10, 20, 30),
-(4, 5, 6, 'four', true, 7, 8, 9),
-(5, 0, 10, 'five', NULL, 15, 20, 25),
-(6, 9, 12, 'six', true, -1, -2, cast('inf' as double)),
-(7, NULL, 7, 'seven', false, 77, 777, NULL),
-(8, 0, 80, NULL, true, 10, 11, 12),
-(9, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
-(127, 1, 2, '127', false, 3, 4, 5)
+(1, 1.0, 1, 'one', true, 1, 1, 1, 0.000000001, 1.11, 1),
+(2, -2, 20, 'two', false, 0, 1, NULL, 0.000000002, 2.22, 2),
+(3, 0, NULL, 'three', false, 10, 20, 30, 0.000000040, 50.00, 60),
+(4, 5, 6, 'four', true, 7, 8, 9, 0.000000010, 11.11, 12),
+(5, 0, 10, 'five', NULL, 15, 20, 25, 0.000000030, 35.35, 40),
+(6, 9, 12, 'six', true, -1, -2, cast('inf' as double), -0.000000001, -1.11, -1),
+(7, NULL, 7, 'seven', false, 77, 777, NULL, NULL, NULL, NULL),
+(8, 0, 80, NULL, true, 10, 11, 12, 0.000000013, 0.14, 15),
+(9, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+(127, 1, 2, '127', false, 3, 4, 5, 0.000000000, 0.00, 0)
 ---- RESULTS
 : 10
 ====
@@ -29,19 +31,19 @@ delete from tdata where id = 1
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tdata
-2,-2,20,'two',false,0,1,NULL
-3,0,NULL,'three',false,10,20,30
-4,5,6,'four',true,7,8,9
-5,0,10,'five',NULL,15,20,25
-6,9,12,'six',true,-1,-2,Infinity
-7,NULL,7,'seven',false,77,777,NULL
-8,0,80,'NULL',true,10,11,12
-9,NULL,NULL,'NULL',NULL,NULL,NULL,NULL
-127,1,2,'127',false,3,4,5
+2,-2,20,'two',false,0,1,NULL,0.000000002,2.22,2
+3,0,NULL,'three',false,10,20,30,0.000000040,50.00,60
+4,5,6,'four',true,7,8,9,0.000000010,11.11,12
+5,0,10,'five',NULL,15,20,25,0.000000030,35.35,40
+6,9,12,'six',true,-1,-2,Infinity,-0.000000001,-1.11,-1
+7,NULL,7,'seven',false,77,777,NULL,NULL,NULL,NULL
+8,0,80,'NULL',true,10,11,12,0.000000013,0.14,15
+9,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL
+127,1,2,'127',false,3,4,5,0.000000000,0.00,0
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # predicate on key, NULL
@@ -50,19 +52,19 @@ delete from tdata where id is NULL
 NumModifiedRows: 0
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tdata
-2,-2,20,'two',false,0,1,NULL
-3,0,NULL,'three',false,10,20,30
-4,5,6,'four',true,7,8,9
-5,0,10,'five',NULL,15,20,25
-6,9,12,'six',true,-1,-2,Infinity
-7,NULL,7,'seven',false,77,777,NULL
-8,0,80,'NULL',true,10,11,12
-9,NULL,NULL,'NULL',NULL,NULL,NULL,NULL
-127,1,2,'127',false,3,4,5
+2,-2,20,'two',false,0,1,NULL,0.000000002,2.22,2
+3,0,NULL,'three',false,10,20,30,0.000000040,50.00,60
+4,5,6,'four',true,7,8,9,0.000000010,11.11,12
+5,0,10,'five',NULL,15,20,25,0.000000030,35.35,40
+6,9,12,'six',true,-1,-2,Infinity,-0.000000001,-1.11,-1
+7,NULL,7,'seven',false,77,777,NULL,NULL,NULL,NULL
+8,0,80,'NULL',true,10,11,12,0.000000013,0.14,15
+9,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL
+127,1,2,'127',false,3,4,5,0.000000000,0.00,0
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # predicate on key, nothing is deleted
@@ -71,19 +73,19 @@ delete from tdata where id = 10
 NumModifiedRows: 0
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tdata
-2,-2,20,'two',false,0,1,NULL
-3,0,NULL,'three',false,10,20,30
-4,5,6,'four',true,7,8,9
-5,0,10,'five',NULL,15,20,25
-6,9,12,'six',true,-1,-2,Infinity
-7,NULL,7,'seven',false,77,777,NULL
-8,0,80,'NULL',true,10,11,12
-9,NULL,NULL,'NULL',NULL,NULL,NULL,NULL
-127,1,2,'127',false,3,4,5
+2,-2,20,'two',false,0,1,NULL,0.000000002,2.22,2
+3,0,NULL,'three',false,10,20,30,0.000000040,50.00,60
+4,5,6,'four',true,7,8,9,0.000000010,11.11,12
+5,0,10,'five',NULL,15,20,25,0.000000030,35.35,40
+6,9,12,'six',true,-1,-2,Infinity,-0.000000001,-1.11,-1
+7,NULL,7,'seven',false,77,777,NULL,NULL,NULL,NULL
+8,0,80,'NULL',true,10,11,12,0.000000013,0.14,15
+9,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL
+127,1,2,'127',false,3,4,5,0.000000000,0.00,0
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # predicate on key, boundary value
@@ -92,18 +94,18 @@ delete from tdata where id = max_tinyint()
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tdata
-2,-2,20,'two',false,0,1,NULL
-3,0,NULL,'three',false,10,20,30
-4,5,6,'four',true,7,8,9
-5,0,10,'five',NULL,15,20,25
-6,9,12,'six',true,-1,-2,Infinity
-7,NULL,7,'seven',false,77,777,NULL
-8,0,80,'NULL',true,10,11,12
-9,NULL,NULL,'NULL',NULL,NULL,NULL,NULL
+2,-2,20,'two',false,0,1,NULL,0.000000002,2.22,2
+3,0,NULL,'three',false,10,20,30,0.000000040,50.00,60
+4,5,6,'four',true,7,8,9,0.000000010,11.11,12
+5,0,10,'five',NULL,15,20,25,0.000000030,35.35,40
+6,9,12,'six',true,-1,-2,Infinity,-0.000000001,-1.11,-1
+7,NULL,7,'seven',false,77,777,NULL,NULL,NULL,NULL
+8,0,80,'NULL',true,10,11,12,0.000000013,0.14,15
+9,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # compound predicate on key
@@ -112,17 +114,17 @@ delete from tdata where id > 6 and id < 8
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tdata
-2,-2,20,'two',false,0,1,NULL
-3,0,NULL,'three',false,10,20,30
-4,5,6,'four',true,7,8,9
-5,0,10,'five',NULL,15,20,25
-6,9,12,'six',true,-1,-2,Infinity
-8,0,80,'NULL',true,10,11,12
-9,NULL,NULL,'NULL',NULL,NULL,NULL,NULL
+2,-2,20,'two',false,0,1,NULL,0.000000002,2.22,2
+3,0,NULL,'three',false,10,20,30,0.000000040,50.00,60
+4,5,6,'four',true,7,8,9,0.000000010,11.11,12
+5,0,10,'five',NULL,15,20,25,0.000000030,35.35,40
+6,9,12,'six',true,-1,-2,Infinity,-0.000000001,-1.11,-1
+8,0,80,'NULL',true,10,11,12,0.000000013,0.14,15
+9,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # predicate on key, multiple rows
@@ -131,23 +133,23 @@ delete from tdata where id % 4 = 0
 NumModifiedRows: 2
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tdata
-2,-2,20,'two',false,0,1,NULL
-3,0,NULL,'three',false,10,20,30
-5,0,10,'five',NULL,15,20,25
-6,9,12,'six',true,-1,-2,Infinity
-9,NULL,NULL,'NULL',NULL,NULL,NULL,NULL
+2,-2,20,'two',false,0,1,NULL,0.000000002,2.22,2
+3,0,NULL,'three',false,10,20,30,0.000000040,50.00,60
+5,0,10,'five',NULL,15,20,25,0.000000030,35.35,40
+6,9,12,'six',true,-1,-2,Infinity,-0.000000001,-1.11,-1
+9,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # insert new values, including some that were previously deleted
 insert into table tdata values
-(10, 20, 30, 'ten', true, 40, 50, 60),
-(1, 1.0, 1, 'one', true, 1, 1, 1),
-(11, -11, 11, 'eleven', false, 1, 11, 111),
-(8, 0, 80, NULL, true, 10, 11, 12)
+(10, 20, 30, 'ten', true, 40, 50, 60, 0.000000070, 80.80, 90),
+(1, 1.0, 1, 'one', true, 1, 1, 1, 0.000000001, 1.11, 1),
+(11, -11, 11, 'eleven', false, 1, 11, 111, 0.000000011, 11.00, 11),
+(8, 0, 80, NULL, true, 10, 11, 12, 0.000000013, 0.14, 15)
 ====
 ---- QUERY
 # single row, predicate on non-key
@@ -156,18 +158,18 @@ delete from tdata where valv = 'five'
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tdata
-2,-2,20,'two',false,0,1,NULL
-3,0,NULL,'three',false,10,20,30
-6,9,12,'six',true,-1,-2,Infinity
-9,NULL,NULL,'NULL',NULL,NULL,NULL,NULL
-10,20,30,'ten',true,40,50,60
-1,1.0,1,'one',true,1,1,1
-11,-11,11,'eleven',false,1,11,111
-8,0,80,'NULL',true,10,11,12
+2,-2,20,'two',false,0,1,NULL,0.000000002,2.22,2
+3,0,NULL,'three',false,10,20,30,0.000000040,50.00,60
+6,9,12,'six',true,-1,-2,Infinity,-0.000000001,-1.11,-1
+9,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL
+10,20,30,'ten',true,40,50,60,0.000000070,80.80,90
+1,1.0,1,'one',true,1,1,1,0.000000001,1.11,1
+11,-11,11,'eleven',false,1,11,111,0.000000011,11.00,11
+8,0,80,'NULL',true,10,11,12,0.000000013,0.14,15
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # predicate on non-key, NULL
@@ -176,17 +178,17 @@ delete from tdata where valb is NULL
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tdata
-2,-2,20,'two',false,0,1,NULL
-3,0,NULL,'three',false,10,20,30
-6,9,12,'six',true,-1,-2,Infinity
-10,20,30,'ten',true,40,50,60
-1,1.0,1,'one',true,1,1,1
-11,-11,11,'eleven',false,1,11,111
-8,0,80,'NULL',true,10,11,12
+2,-2,20,'two',false,0,1,NULL,0.000000002,2.22,2
+3,0,NULL,'three',false,10,20,30,0.000000040,50.00,60
+6,9,12,'six',true,-1,-2,Infinity,-0.000000001,-1.11,-1
+10,20,30,'ten',true,40,50,60,0.000000070,80.80,90
+1,1.0,1,'one',true,1,1,1,0.000000001,1.11,1
+11,-11,11,'eleven',false,1,11,111,0.000000011,11.00,11
+8,0,80,'NULL',true,10,11,12,0.000000013,0.14,15
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # predicate on non-key, nothing is deleted
@@ -195,17 +197,17 @@ delete from tdata where vals = -100
 NumModifiedRows: 0
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tdata
-2,-2,20,'two',false,0,1,NULL
-3,0,NULL,'three',false,10,20,30
-6,9,12,'six',true,-1,-2,Infinity
-10,20,30,'ten',true,40,50,60
-1,1.0,1,'one',true,1,1,1
-11,-11,11,'eleven',false,1,11,111
-8,0,80,'NULL',true,10,11,12
+2,-2,20,'two',false,0,1,NULL,0.000000002,2.22,2
+3,0,NULL,'three',false,10,20,30,0.000000040,50.00,60
+6,9,12,'six',true,-1,-2,Infinity,-0.000000001,-1.11,-1
+10,20,30,'ten',true,40,50,60,0.000000070,80.80,90
+1,1.0,1,'one',true,1,1,1,0.000000001,1.11,1
+11,-11,11,'eleven',false,1,11,111,0.000000011,11.00,11
+8,0,80,'NULL',true,10,11,12,0.000000013,0.14,15
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # predicate on non-key, compound predicate
@@ -214,16 +216,16 @@ delete from tdata where valf = 0 and vali = 80
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tdata
-2,-2,20,'two',false,0,1,NULL
-3,0,NULL,'three',false,10,20,30
-6,9,12,'six',true,-1,-2,Infinity
-10,20,30,'ten',true,40,50,60
-1,1.0,1,'one',true,1,1,1
-11,-11,11,'eleven',false,1,11,111
+2,-2,20,'two',false,0,1,NULL,0.000000002,2.22,2
+3,0,NULL,'three',false,10,20,30,0.000000040,50.00,60
+6,9,12,'six',true,-1,-2,Infinity,-0.000000001,-1.11,-1
+10,20,30,'ten',true,40,50,60,0.000000070,80.80,90
+1,1.0,1,'one',true,1,1,1,0.000000001,1.11,1
+11,-11,11,'eleven',false,1,11,111,0.000000011,11.00,11
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # predicate on non-key, multiple rows
@@ -232,14 +234,14 @@ delete from tdata where vals % 10 = 0
 NumModifiedRows: 2
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tdata
-2,-2,20,'two',false,0,1,NULL
-6,9,12,'six',true,-1,-2,Infinity
-1,1.0,1,'one',true,1,1,1
-11,-11,11,'eleven',false,1,11,111
+2,-2,20,'two',false,0,1,NULL,0.000000002,2.22,2
+6,9,12,'six',true,-1,-2,Infinity,-0.000000001,-1.11,-1
+1,1.0,1,'one',true,1,1,1,0.000000001,1.11,1
+11,-11,11,'eleven',false,1,11,111,0.000000011,11.00,11
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # 'from' syntax - the join results in four deletes, 3 of which fail
@@ -248,13 +250,13 @@ delete a from tdata a, tdata b where a.id = 11
 NumModifiedRows: 1
 NumRowErrors: 3
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tdata
-2,-2,20,'two',false,0,1,NULL
-6,9,12,'six',true,-1,-2,Infinity
-1,1.0,1,'one',true,1,1,1
+2,-2,20,'two',false,0,1,NULL,0.000000002,2.22,2
+6,9,12,'six',true,-1,-2,Infinity,-0.000000001,-1.11,-1
+1,1.0,1,'one',true,1,1,1,0.000000001,1.11,1
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # Try to delete a row with a primary key value that is not covered by the existing range
@@ -264,18 +266,56 @@ delete from tdata where id = 10001
 NumModifiedRows: 0
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tdata
-2,-2,20,'two',false,0,1,NULL
-6,9,12,'six',true,-1,-2,Infinity
-1,1.0,1,'one',true,1,1,1
+2,-2,20,'two',false,0,1,NULL,0.000000002,2.22,2
+6,9,12,'six',true,-1,-2,Infinity,-0.000000001,-1.11,-1
+1,1.0,1,'one',true,1,1,1,0.000000001,1.11,1
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
+====
+---- QUERY
+# Add a couple more rows back
+insert into table tdata values
+(3, 0, NULL, 'three', false, 10, 20, 30, 0.000000040, 50.00, 60),
+(4, 5, 6, 'four', true, 7, 8, 9, 0.000000010, 11.11, 12),
+(5, 0, 10, 'five', NULL, 15, 20, 25, 0.000000030, 35.35, 40)
+---- RESULTS
+: 3
+====
+---- QUERY
+# predicate on decimal, multiple rows
+delete from tdata where valdec8 < 11.11
+---- RUNTIME_PROFILE
+NumModifiedRows: 3
+NumRowErrors: 0
+---- LABELS
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
+---- DML_RESULTS: tdata
+3,0,NULL,'three',false,10,20,30,0.000000040,50.00,60
+4,5,6,'four',true,7,8,9,0.000000010,11.11,12
+5,0,10,'five',NULL,15,20,25,0.000000030,35.35,40
+---- TYPES
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
+====
+---- QUERY
+# predicate on decimal, single row
+delete from tdata where valdec4 = 0.000000030
+---- RUNTIME_PROFILE
+NumModifiedRows: 1
+NumRowErrors: 0
+---- LABELS
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
+---- DML_RESULTS: tdata
+3,0,NULL,'three',false,10,20,30,0.000000040,50.00,60
+4,5,6,'four',true,7,8,9,0.000000010,11.11,12
+---- TYPES
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 insert into tdata
 select cast(id + 100 as int), float_col, bigint_col, string_col, bool_col, tinyint_col,
-smallint_col, double_col
+smallint_col, double_col, NULL, NULL, NULL
 from functional_kudu.alltypes
 ---- RESULTS
 : 7300
@@ -287,13 +327,13 @@ NumRowErrors: 0
 # Test a larger DELETE
 delete from tdata where id > -1
 ---- RUNTIME_PROFILE
-NumModifiedRows: 7303
+NumModifiedRows: 7302
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, VALDEC4, VALDEC8, VALDEC16
 ---- DML_RESULTS: tdata
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 create table multiple_key_cols

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/testdata/workloads/functional-query/queries/QueryTest/kudu_describe.test
----------------------------------------------------------------------
diff --git a/testdata/workloads/functional-query/queries/QueryTest/kudu_describe.test b/testdata/workloads/functional-query/queries/QueryTest/kudu_describe.test
index 687ca31..daaa18f 100644
--- a/testdata/workloads/functional-query/queries/QueryTest/kudu_describe.test
+++ b/testdata/workloads/functional-query/queries/QueryTest/kudu_describe.test
@@ -45,3 +45,23 @@ NAME,TYPE,COMMENT,PRIMARY_KEY,NULLABLE,DEFAULT_VALUE,ENCODING,COMPRESSION,BLOCK_
 ---- TYPES
 STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING
 ====
+---- QUERY
+# Test decimal columns and primary key
+create table describe_decimal_test
+(
+ decimal_default decimal PRIMARY KEY,
+ decimal_4 decimal(9, 9) not null,
+ decimal_8 decimal(18, 2) not null default 100.00,
+ decimal_16 decimal(38, 0) null)
+stored as kudu;
+describe describe_decimal_test;
+---- LABELS
+NAME,TYPE,COMMENT,PRIMARY_KEY,NULLABLE,DEFAULT_VALUE,ENCODING,COMPRESSION,BLOCK_SIZE
+---- RESULTS
+'decimal_default','decimal(9,0)','','true','false','','AUTO_ENCODING','DEFAULT_COMPRESSION','0'
+'decimal_4','decimal(9,9)','','false','false','','AUTO_ENCODING','DEFAULT_COMPRESSION','0'
+'decimal_8','decimal(18,2)','','false','false','100.00','AUTO_ENCODING','DEFAULT_COMPRESSION','0'
+'decimal_16','decimal(38,0)','','false','true','','AUTO_ENCODING','DEFAULT_COMPRESSION','0'
+---- TYPES
+STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING,STRING
+====

http://git-wip-us.apache.org/repos/asf/impala/blob/0c8eba07/testdata/workloads/functional-query/queries/QueryTest/kudu_insert.test
----------------------------------------------------------------------
diff --git a/testdata/workloads/functional-query/queries/QueryTest/kudu_insert.test b/testdata/workloads/functional-query/queries/QueryTest/kudu_insert.test
index 420e42c..6bba77a 100644
--- a/testdata/workloads/functional-query/queries/QueryTest/kudu_insert.test
+++ b/testdata/workloads/functional-query/queries/QueryTest/kudu_insert.test
@@ -3,7 +3,8 @@
 create table tdata
   (id int primary key, valf float null, vali bigint null, valv string null,
    valb boolean null, valt tinyint null, vals smallint null, vald double null,
-   ts timestamp)
+   ts timestamp, decimal4 decimal(9,9) null, decimal8 decimal(18,2) null,
+   decimal16 decimal(38, 0) null)
   PARTITION BY RANGE (PARTITION VALUES < 10, PARTITION 10 <= VALUES < 30,
   PARTITION 30 <= VALUES) STORED AS KUDU
 ---- RESULTS
@@ -11,30 +12,30 @@ create table tdata
 ---- QUERY
 # VALUES, single row, all target cols, no errors
 insert into tdata values (1, 1, 1, 'one', true, 1, 1, 1,
-  cast('1987-05-19 00:00:00' as timestamp))
+  cast('1987-05-19 00:00:00' as timestamp), 0.000000001, 1.00, 1)
 ---- RUNTIME_PROFILE
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS, DECIMAL4, DECIMAL8, DECIMAL16
 ---- DML_RESULTS: tdata
-1,1,1,'one',true,1,1,1,1987-05-19 00:00:00
+1,1,1,'one',true,1,1,1,1987-05-19 00:00:00,0.000000001,1.00,1
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # VALUES, single row, all target cols, NULL
-insert into tdata values (2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
+insert into tdata values (2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
 ---- RUNTIME_PROFILE
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS, DECIMAL4, DECIMAL8, DECIMAL16
 ---- DML_RESULTS: tdata
-1,1,1,'one',true,1,1,1,1987-05-19 00:00:00
-2,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL
+1,1,1,'one',true,1,1,1,1987-05-19 00:00:00,0.000000001,1.00,1
+2,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # VALUES, single row, all target cols, boundary values. The timestamp value is the max
@@ -43,18 +44,19 @@ INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP
 insert into tdata values
 (3, cast('nan' as float), max_bigint(), '', true, min_tinyint(), max_smallint(),
   cast('-inf' as double),
-  nanoseconds_add(cast('9999-12-31 23:59:59' as timestamp), 999999999))
+  nanoseconds_add(cast('9999-12-31 23:59:59' as timestamp), 999999999),
+  0.999999999, 9999999999999999.99, 99999999999999999999999999999999999999)
 ---- RUNTIME_PROFILE
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS, DECIMAL4, DECIMAL8, DECIMAL16
 ---- DML_RESULTS: tdata
-1,1,1,'one',true,1,1,1,1987-05-19 00:00:00
-2,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL
-3,NaN,9223372036854775807,'',true,-128,32767,-Infinity,9999-12-31 23:59:59.999999000
+1,1,1,'one',true,1,1,1,1987-05-19 00:00:00,0.000000001,1.00,1
+2,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+3,NaN,9223372036854775807,'',true,-128,32767,-Infinity,9999-12-31 23:59:59.999999000,0.999999999,9999999999999999.99,99999999999999999999999999999999999999
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # VALUES, single row, subset of target cols
@@ -63,36 +65,36 @@ insert into tdata (valb, vald, id) values (true, 0, 4)
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS, DECIMAL4, DECIMAL8, DECIMAL16
 ---- DML_RESULTS: tdata
-1,1,1,'one',true,1,1,1,1987-05-19 00:00:00
-2,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL
-3,NaN,9223372036854775807,'',true,-128,32767,-Infinity,9999-12-31 23:59:59.999999000
-4,NULL,NULL,'NULL',true,NULL,NULL,0,NULL
+1,1,1,'one',true,1,1,1,1987-05-19 00:00:00,0.000000001,1.00,1
+2,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+3,NaN,9223372036854775807,'',true,-128,32767,-Infinity,9999-12-31 23:59:59.999999000,0.999999999,9999999999999999.99,99999999999999999999999999999999999999
+4,NULL,NULL,'NULL',true,NULL,NULL,0,NULL,NULL,NULL,NULL
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # VALUES, multiple rows, all target cols
 insert into tdata values
-(5, 5.0, 5, 'five', false, NULL, NULL, NULL, NULL),
-(6, 16, 60, '', true, 0, -1, -6, cast('2010-12-31 23:59:59' as timestamp)),
-(7, NULL, 10, NULL, false, max_tinyint(), -7, 2, cast('1400-01-01 00:00:00' as timestamp))
+(5, 5.0, 5, 'five', false, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+(6, 16, 60, '', true, 0, -1, -6, cast('2010-12-31 23:59:59' as timestamp), -0.000000001, -1.00, -1),
+(7, NULL, 10, NULL, false, max_tinyint(), -7, 2, cast('1400-01-01 00:00:00' as timestamp), 0.000000000, 0.00, 0)
 ---- RUNTIME_PROFILE
 NumModifiedRows: 3
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS, DECIMAL4, DECIMAL8, DECIMAL16
 ---- DML_RESULTS: tdata
-1,1,1,'one',true,1,1,1,1987-05-19 00:00:00
-2,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL
-3,NaN,9223372036854775807,'',true,-128,32767,-Infinity,9999-12-31 23:59:59.999999000
-4,NULL,NULL,'NULL',true,NULL,NULL,0,NULL
-5,5.0,5,'five',false,NULL,NULL,NULL,NULL
-6,16,60,'',true,0,-1,-6,2010-12-31 23:59:59
-7,NULL,10,'NULL',false,127,-7,2,1400-01-01 00:00:00
+1,1,1,'one',true,1,1,1,1987-05-19 00:00:00,0.000000001,1.00,1
+2,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+3,NaN,9223372036854775807,'',true,-128,32767,-Infinity,9999-12-31 23:59:59.999999000,0.999999999,9999999999999999.99,99999999999999999999999999999999999999
+4,NULL,NULL,'NULL',true,NULL,NULL,0,NULL,NULL,NULL,NULL
+5,5.0,5,'five',false,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+6,16,60,'',true,0,-1,-6,2010-12-31 23:59:59,-0.000000001,-1.00,-1
+7,NULL,10,'NULL',false,127,-7,2,1400-01-01 00:00:00,0.000000000,0.00,0
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # VALUES, multiple rows, subset of cols
@@ -103,44 +105,44 @@ insert into tdata (valv, valf, vali, id) values
 NumModifiedRows: 2
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS, DECIMAL4, DECIMAL8, DECIMAL16
 ---- DML_RESULTS: tdata
-1,1,1,'one',true,1,1,1,1987-05-19 00:00:00
-2,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL
-3,NaN,9223372036854775807,'',true,-128,32767,-Infinity,9999-12-31 23:59:59.999999000
-4,NULL,NULL,'NULL',true,NULL,NULL,0,NULL
-5,5.0,5,'five',false,NULL,NULL,NULL,NULL
-6,16,60,'',true,0,-1,-6,2010-12-31 23:59:59
-7,NULL,10,'NULL',false,127,-7,2,1400-01-01 00:00:00
-8,88,888,'eight',NULL,NULL,NULL,NULL,NULL
-9,-9,-99,'NULL',NULL,NULL,NULL,NULL,NULL
+1,1,1,'one',true,1,1,1,1987-05-19 00:00:00,0.000000001,1.00,1
+2,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+3,NaN,9223372036854775807,'',true,-128,32767,-Infinity,9999-12-31 23:59:59.999999000,0.999999999,9999999999999999.99,99999999999999999999999999999999999999
+4,NULL,NULL,'NULL',true,NULL,NULL,0,NULL,NULL,NULL,NULL
+5,5.0,5,'five',false,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+6,16,60,'',true,0,-1,-6,2010-12-31 23:59:59,-0.000000001,-1.00,-1
+7,NULL,10,'NULL',false,127,-7,2,1400-01-01 00:00:00,0.000000000,0.00,0
+8,88,888,'eight',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+9,-9,-99,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # SELECT, single row, all target cols
 insert into tdata
 select id, float_col, bigint_col, string_col, bool_col, tinyint_col, smallint_col,
-double_col, timestamp_col
+double_col, timestamp_col, NULL, NULL, NULL
 from functional.alltypes where id = 10
 ---- RUNTIME_PROFILE
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS, DECIMAL4, DECIMAL8, DECIMAL16
 ---- DML_RESULTS: tdata
-1,1,1,'one',true,1,1,1,1987-05-19 00:00:00
-2,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL
-3,NaN,9223372036854775807,'',true,-128,32767,-Infinity,9999-12-31 23:59:59.999999000
-4,NULL,NULL,'NULL',true,NULL,NULL,0,NULL
-5,5.0,5,'five',false,NULL,NULL,NULL,NULL
-6,16,60,'',true,0,-1,-6,2010-12-31 23:59:59
-7,NULL,10,'NULL',false,127,-7,2,1400-01-01 00:00:00
-8,88,888,'eight',NULL,NULL,NULL,NULL,NULL
-9,-9,-99,'NULL',NULL,NULL,NULL,NULL,NULL
-10,0,0,'0',true,0,0,0,2009-01-02 00:10:00.450000000
+1,1,1,'one',true,1,1,1,1987-05-19 00:00:00,0.000000001,1.00,1
+2,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+3,NaN,9223372036854775807,'',true,-128,32767,-Infinity,9999-12-31 23:59:59.999999000,0.999999999,9999999999999999.99,99999999999999999999999999999999999999
+4,NULL,NULL,'NULL',true,NULL,NULL,0,NULL,NULL,NULL,NULL
+5,5.0,5,'five',false,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+6,16,60,'',true,0,-1,-6,2010-12-31 23:59:59,-0.000000001,-1.00,-1
+7,NULL,10,'NULL',false,127,-7,2,1400-01-01 00:00:00,0.000000000,0.00,0
+8,88,888,'eight',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+9,-9,-99,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+10,0,0,'0',true,0,0,0,2009-01-02 00:10:00.450000000,NULL,NULL,NULL
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # SELECT, single row, subset of cols
@@ -151,21 +153,21 @@ from functional.alltypes where id = 11
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS, DECIMAL4, DECIMAL8, DECIMAL16
 ---- DML_RESULTS: tdata
-1,1,1,'one',true,1,1,1,1987-05-19 00:00:00
-2,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL
-3,NaN,9223372036854775807,'',true,-128,32767,-Infinity,9999-12-31 23:59:59.999999000
-4,NULL,NULL,'NULL',true,NULL,NULL,0,NULL
-5,5.0,5,'five',false,NULL,NULL,NULL,NULL
-6,16,60,'',true,0,-1,-6,2010-12-31 23:59:59
-7,NULL,10,'NULL',false,127,-7,2,1400-01-01 00:00:00
-8,88,888,'eight',NULL,NULL,NULL,NULL,NULL
-9,-9,-99,'NULL',NULL,NULL,NULL,NULL,NULL
-10,0,0,'0',true,0,0,0,2009-01-02 00:10:00.450000000
-11,NULL,10,'NULL',false,NULL,NULL,10.1,2009-01-02 00:11:00.450000000
+1,1,1,'one',true,1,1,1,1987-05-19 00:00:00,0.000000001,1.00,1
+2,NULL,NULL,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+3,NaN,9223372036854775807,'',true,-128,32767,-Infinity,9999-12-31 23:59:59.999999000,0.999999999,9999999999999999.99,99999999999999999999999999999999999999
+4,NULL,NULL,'NULL',true,NULL,NULL,0,NULL,NULL,NULL,NULL
+5,5.0,5,'five',false,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+6,16,60,'',true,0,-1,-6,2010-12-31 23:59:59,-0.000000001,-1.00,-1
+7,NULL,10,'NULL',false,127,-7,2,1400-01-01 00:00:00,0.000000000,0.00,0
+8,88,888,'eight',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+9,-9,-99,'NULL',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
+10,0,0,'0',true,0,0,0,2009-01-02 00:10:00.450000000,NULL,NULL,NULL
+11,NULL,10,'NULL',false,NULL,NULL,10.1,2009-01-02 00:11:00.450000000,NULL,NULL,NULL
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 delete tdata
@@ -175,18 +177,18 @@ delete tdata
 # SELECT, multiple rows, all target cols
 insert into tdata
 select id, float_col, bigint_col, string_col, bool_col, tinyint_col, smallint_col,
-double_col, timestamp_col
+double_col, timestamp_col, NULL, NULL, NULL
 from functional.alltypes where id < 2
 ---- RUNTIME_PROFILE
 NumModifiedRows: 2
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS, DECIMAL4, DECIMAL8, DECIMAL16
 ---- DML_RESULTS: tdata
-0,0,0,'0',true,0,0,0,2009-01-01 00:00:00
-1,1.100000023841858,10,'1',false,1,1,10.1,2009-01-01 00:01:00
+0,0,0,'0',true,0,0,0,2009-01-01 00:00:00,NULL,NULL,NULL
+1,1.100000023841858,10,'1',false,1,1,10.1,2009-01-01 00:01:00,NULL,NULL,NULL
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # SELECT, multiple rows, subset of cols
@@ -197,20 +199,20 @@ from functional.alltypes where id > 2 and id < 6
 NumModifiedRows: 3
 NumRowErrors: 0
 ---- LABELS
-ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS
+ID, VALF, VALI, VALV, VALB, VALT, VALS, VALD, TS, DECIMAL4, DECIMAL8, DECIMAL16
 ---- DML_RESULTS: tdata
-0,0,0,'0',true,0,0,0,2009-01-01 00:00:00
-1,1.100000023841858,10,'1',false,1,1,10.1,2009-01-01 00:01:00
-3,NULL,NULL,'NULL',NULL,3,3,30.3,2009-01-01 00:03:00.300000000
-4,NULL,NULL,'NULL',NULL,4,4,40.4,2009-01-01 00:04:00.600000000
-5,NULL,NULL,'NULL',NULL,5,5,50.5,2009-01-01 00:05:00.100000000
+0,0,0,'0',true,0,0,0,2009-01-01 00:00:00,NULL,NULL,NULL
+1,1.100000023841858,10,'1',false,1,1,10.1,2009-01-01 00:01:00,NULL,NULL,NULL
+3,NULL,NULL,'NULL',NULL,3,3,30.3,2009-01-01 00:03:00.300000000,NULL,NULL,NULL
+4,NULL,NULL,'NULL',NULL,4,4,40.4,2009-01-01 00:04:00.600000000,NULL,NULL,NULL
+5,NULL,NULL,'NULL',NULL,5,5,50.5,2009-01-01 00:05:00.100000000,NULL,NULL,NULL
 ---- TYPES
-INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP
+INT,FLOAT,BIGINT,STRING,BOOLEAN,TINYINT,SMALLINT,DOUBLE,TIMESTAMP,DECIMAL,DECIMAL,DECIMAL
 ====
 ---- QUERY
 # Make sure we can insert empty strings into string columns and that we can scan them
 # back.
-insert into tdata values (320, 2.0, 932, cast('' as string), false, 0, 0, 0, NULL)
+insert into tdata values (320, 2.0, 932, cast('' as string), false, 0, 0, 0, NULL, NULL, NULL, NULL)
 ---- RESULTS
 : 1
 ---- RUNTIME_PROFILE
@@ -226,7 +228,7 @@ INT,STRING,BOOLEAN
 ====
 ---- QUERY
 insert into tdata values
-(666, cast(1.2 as float), 43, cast('z' as string), true, 0, 0, 0, NULL)
+(666, cast(1.2 as float), 43, cast('z' as string), true, 0, 0, 0, NULL, NULL, NULL, NULL)
 ---- RESULTS
 : 1
 ---- RUNTIME_PROFILE
@@ -236,7 +238,7 @@ NumRowErrors: 0
 ---- QUERY
 # insert row with primary key that already exists
 insert into tdata values
-(666, cast(1.2 as float), 43, cast('z' as VARCHAR(20)), true, 0, 0, 0, NULL)
+(666, cast(1.2 as float), 43, cast('z' as VARCHAR(20)), true, 0, 0, 0, NULL, NULL, NULL, NULL)
 ---- RESULTS
 : 0
 ---- RUNTIME_PROFILE
@@ -319,7 +321,8 @@ NumRowErrors: 0
 # Table with default values
 create table tbl_with_defaults (a int primary key, b int null default 10,
   c int not null default 100, d int default 1000, e int null, f int not null,
-  g string default 'test', h boolean default true) partition by hash (a)
+  g string default 'test', h boolean default true,
+  i decimal(9, 2) default 1111.11) partition by hash (a)
   partitions 3 stored as kudu
 ---- RESULTS
 ====
@@ -329,62 +332,62 @@ insert into tbl_with_defaults (a, f) values (1, 1), (2, 2), (3, 3), (4, 4)
 NumModifiedRows: 4
 NumRowErrors: 0
 ---- LABELS
-A, B, C, D, E, F, G, H
+A, B, C, D, E, F, G, H, I
 ---- DML_RESULTS: tbl_with_defaults
-1,10,100,1000,NULL,1,'test',true
-2,10,100,1000,NULL,2,'test',true
-3,10,100,1000,NULL,3,'test',true
-4,10,100,1000,NULL,4,'test',true
+1,10,100,1000,NULL,1,'test',true,1111.11
+2,10,100,1000,NULL,2,'test',true,1111.11
+3,10,100,1000,NULL,3,'test',true,1111.11
+4,10,100,1000,NULL,4,'test',true,1111.11
 ---- TYPES
-INT,INT,INT,INT,INT,INT,STRING,BOOLEAN
+INT,INT,INT,INT,INT,INT,STRING,BOOLEAN,DECIMAL
 ====
 ---- QUERY
-insert into tbl_with_defaults values (5, 5, 5, 5, 5, 5, 'row', false)
+insert into tbl_with_defaults values (5, 5, 5, 5, 5, 5, 'row', false, 55555.55)
 ---- RUNTIME_PROFILE
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-A, B, C, D, E, F, G, H
+A, B, C, D, E, F, G, H, I
 ---- DML_RESULTS: tbl_with_defaults
-1,10,100,1000,NULL,1,'test',true
-2,10,100,1000,NULL,2,'test',true
-3,10,100,1000,NULL,3,'test',true
-4,10,100,1000,NULL,4,'test',true
-5,5,5,5,5,5,'row',false
+1,10,100,1000,NULL,1,'test',true,1111.11
+2,10,100,1000,NULL,2,'test',true,1111.11
+3,10,100,1000,NULL,3,'test',true,1111.11
+4,10,100,1000,NULL,4,'test',true,1111.11
+5,5,5,5,5,5,'row',false,55555.55
 ---- TYPES
-INT,INT,INT,INT,INT,INT,STRING,BOOLEAN
+INT,INT,INT,INT,INT,INT,STRING,BOOLEAN,DECIMAL
 ====
 ---- QUERY
-alter table tbl_with_defaults add columns (i int null, j int not null default 10000)
+alter table tbl_with_defaults add columns (j int null, k int not null default 10000)
 ---- RESULTS
 ====
 ---- QUERY
 select * from tbl_with_defaults
 ---- RESULTS
-1,10,100,1000,NULL,1,'test',true,NULL,10000
-2,10,100,1000,NULL,2,'test',true,NULL,10000
-3,10,100,1000,NULL,3,'test',true,NULL,10000
-4,10,100,1000,NULL,4,'test',true,NULL,10000
-5,5,5,5,5,5,'row',false,NULL,10000
+1,10,100,1000,NULL,1,'test',true,1111.11,NULL,10000
+2,10,100,1000,NULL,2,'test',true,1111.11,NULL,10000
+3,10,100,1000,NULL,3,'test',true,1111.11,NULL,10000
+4,10,100,1000,NULL,4,'test',true,1111.11,NULL,10000
+5,5,5,5,5,5,'row',false,55555.55,NULL,10000
 ---- TYPES
-INT,INT,INT,INT,INT,INT,STRING,BOOLEAN,INT,INT
+INT,INT,INT,INT,INT,INT,STRING,BOOLEAN,DECIMAL,INT,INT
 ====
 ---- QUERY
-insert into tbl_with_defaults values (6,6,6,6,6,6,'another row',false,6,6)
+insert into tbl_with_defaults values (6,6,6,6,6,6,'another row',false,66666.66,6,6)
 ---- RUNTIME_PROFILE
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-A, B, C, D, E, F, G, H, I, J
+A, B, C, D, E, F, G, H, I, J, K
 ---- DML_RESULTS: tbl_with_defaults
-1,10,100,1000,NULL,1,'test',true,NULL,10000
-2,10,100,1000,NULL,2,'test',true,NULL,10000
-3,10,100,1000,NULL,3,'test',true,NULL,10000
-4,10,100,1000,NULL,4,'test',true,NULL,10000
-5,5,5,5,5,5,'row',false,NULL,10000
-6,6,6,6,6,6,'another row',false,6,6
+1,10,100,1000,NULL,1,'test',true,1111.11,NULL,10000
+2,10,100,1000,NULL,2,'test',true,1111.11,NULL,10000
+3,10,100,1000,NULL,3,'test',true,1111.11,NULL,10000
+4,10,100,1000,NULL,4,'test',true,1111.11,NULL,10000
+5,5,5,5,5,5,'row',false,55555.55,NULL,10000
+6,6,6,6,6,6,'another row',false,66666.66,6,6
 ---- TYPES
-INT,INT,INT,INT,INT,INT,STRING,BOOLEAN,INT,INT
+INT,INT,INT,INT,INT,INT,STRING,BOOLEAN,DECIMAL,INT,INT
 ====
 ---- QUERY
 # IMPALA-5217: Try to insert NULL to a 'NOT NULL' col with a target col list that leaves
@@ -402,17 +405,17 @@ insert into tbl_with_defaults (a, b, d, f) values (0, 0, null, 0)
 NumModifiedRows: 1
 NumRowErrors: 0
 ---- LABELS
-A, B, C, D, E, F, G, H, I, J
+A, B, C, D, E, F, G, H, I, J, K
 ---- DML_RESULTS: tbl_with_defaults
-0,0,100,NULL,NULL,0,'test',true,NULL,10000
-1,10,100,1000,NULL,1,'test',true,NULL,10000
-2,10,100,1000,NULL,2,'test',true,NULL,10000
-3,10,100,1000,NULL,3,'test',true,NULL,10000
-4,10,100,1000,NULL,4,'test',true,NULL,10000
-5,5,5,5,5,5,'row',false,NULL,10000
-6,6,6,6,6,6,'another row',false,6,6
+0,0,100,NULL,NULL,0,'test',true,1111.11,NULL,10000
+1,10,100,1000,NULL,1,'test',true,1111.11,NULL,10000
+2,10,100,1000,NULL,2,'test',true,1111.11,NULL,10000
+3,10,100,1000,NULL,3,'test',true,1111.11,NULL,10000
+4,10,100,1000,NULL,4,'test',true,1111.11,NULL,10000
+5,5,5,5,5,5,'row',false,55555.55,NULL,10000
+6,6,6,6,6,6,'another row',false,66666.66,6,6
 ---- TYPES
-INT,INT,INT,INT,INT,INT,STRING,BOOLEAN,INT,INT
+INT,INT,INT,INT,INT,INT,STRING,BOOLEAN,DECIMAL,INT,INT
 ====
 ---- QUERY
 create table multiple_partition_cols (x bigint, y bigint, z string, primary key(x, y))