diff --git a/extensions/functions_rounding_decimal.yaml b/extensions/functions_rounding_decimal.yaml
new file mode 100644
index 000000000..125ca56a7
--- /dev/null
+++ b/extensions/functions_rounding_decimal.yaml
@@ -0,0 +1,80 @@
+%YAML 1.2
+---
+scalar_functions:
+ -
+ name: "ceil"
+ description: >
+ Rounding to the ceiling of the value `x`.
+ impls:
+ - args:
+ - value: decimal
+ name: x
+ return: |-
+ integral_least_num_digits = P - S + 1
+ precision = min(integral_least_num_digits, 38)
+ decimal?
+ -
+ name: "floor"
+ description: >
+ Rounding to the floor of the value `x`.
+ impls:
+ - args:
+ - value: decimal
+ name: x
+ return: |-
+ integral_least_num_digits = P - S + 1
+ precision = min(integral_least_num_digits, 38)
+ decimal?
+ -
+ name: "round"
+ description: >
+ Rounding the value `x` to `s` decimal places.
+ impls:
+ - args:
+ - value: decimal
+ name: x
+ description: >
+ Numerical expression to be rounded.
+ - value: i32
+ name: s
+ description: >
+ Number of decimal places to be rounded to.
+
+ When `s` is a positive number, the rounding
+ is performed to a `s` number of decimal places.
+
+ When `s` is a negative number, the rounding is
+ performed to the left side of the decimal point
+ as specified by `s`.
+
+ The precision and scale of the resultant decimal
+ type will be adjusted from the input decimal type
+ dependent on the value of `s`.
+ options:
+ rounding:
+ description: >
+ When a boundary is computed to lie somewhere between two values,
+ and this value cannot be exactly represented, this specifies how
+ to round it.
+
+ - TIE_TO_EVEN: round to nearest value; if exactly halfway, tie
+ to the even option.
+ - TIE_AWAY_FROM_ZERO: round to nearest value; if exactly
+ halfway, tie away from zero.
+ - TRUNCATE: always round toward zero.
+ - CEILING: always round toward positive infinity.
+ - FLOOR: always round toward negative infinity.
+ - AWAY_FROM_ZERO: round negative values with FLOOR rule, round positive values with CEILING rule
+ - TIE_DOWN: round ties with FLOOR rule
+ - TIE_UP: round ties with CEILING rule
+ - TIE_TOWARDS_ZERO: round ties with TRUNCATE rule
+ - TIE_TO_ODD: round to nearest value; if exactly halfway, tie
+ to the odd option.
+ values: [ TIE_TO_EVEN, TIE_AWAY_FROM_ZERO, TRUNCATE, CEILING, FLOOR,
+ AWAY_FROM_ZERO, TIE_DOWN, TIE_UP, TIE_TOWARDS_ZERO, TIE_TO_ODD ]
+ nullability: DECLARED_OUTPUT
+ return: |-
+ integral_digits = P1 - S1 + 1
+ scale = s > 0 ? min(s, S1) : 0
+ precision = s > 0 ? min(integral_digits + scale, 38) : min(max(integral_num_digits, 1- s), 38)
+ decimal?
diff --git a/tests/cases/rounding_decimal/ceil_decimal.test b/tests/cases/rounding_decimal/ceil_decimal.test
new file mode 100644
index 000000000..bbcf14dc4
--- /dev/null
+++ b/tests/cases/rounding_decimal/ceil_decimal.test
@@ -0,0 +1,7 @@
+### SUBSTRAIT_SCALAR_TEST: v1.0
+### SUBSTRAIT_INCLUDE: '/extensions/functions_rounding_decimal.yaml'
+
+# basic: Basic examples without any special cases
+ceil(2.25::dec<8,2>) = 3::dec<7,0>
+ceil(-65.5::dec<8,2>) = -65::dec<7,0>
+ceil(9.9::dec<2,1>) = 10::dec<2,0>
diff --git a/tests/cases/rounding_decimal/floor_decimal.test b/tests/cases/rounding_decimal/floor_decimal.test
new file mode 100644
index 000000000..d37e0e175
--- /dev/null
+++ b/tests/cases/rounding_decimal/floor_decimal.test
@@ -0,0 +1,6 @@
+### SUBSTRAIT_SCALAR_TEST: v1.0
+### SUBSTRAIT_INCLUDE: '/extensions/functions_rounding_decimal.yaml'
+
+# basic: Basic examples without any special cases
+floor(2.25::dec<8,2>) = 2::dec<7,0>
+floor(-65.5::dec<8,2>) = -66::dec<7,0>
diff --git a/tests/cases/rounding_decimal/round_decimal.test b/tests/cases/rounding_decimal/round_decimal.test
new file mode 100644
index 000000000..38da8f5c4
--- /dev/null
+++ b/tests/cases/rounding_decimal/round_decimal.test
@@ -0,0 +1,11 @@
+### SUBSTRAIT_SCALAR_TEST: v1.0
+### SUBSTRAIT_INCLUDE: '/extensions/functions_rounding_decimal.yaml'
+
+# basic: Basic examples without any special cases
+round(2::dec<2,0>, 2::i32) = 2::dec<3,0>
+round(2.75::dec<8,2>, 1::i32) = 2.8::dec<8,1>
+
+# negative_rounding: Examples with negative rounding
+round(2::dec<2,0>, -2::i32) = 0::dec<2,0>
+round(123::dec<2,0>, -2::i32) = 100::dec<2,0>
+round(8793::dec<2,0>, -2::i32) = 8800::dec<2,0>