|
37 | 37 |
|
38 | 38 | #include "firebird.h" |
39 | 39 | #include <cmath> |
| 40 | +#include <cstddef> |
40 | 41 | #include <stdio.h> |
41 | 42 | #include <string.h> |
42 | 43 | #include <stdlib.h> |
@@ -293,6 +294,32 @@ static void timeStampToUtc(ISC_TIMESTAMP_TZ& timestampTZ, USHORT sessionTimeZone |
293 | 294 | } |
294 | 295 |
|
295 | 296 |
|
| 297 | +static void zeroTzPadding(dsc* to) |
| 298 | +{ |
| 299 | + if (!to || !to->dsc_address) |
| 300 | + return; |
| 301 | + |
| 302 | + size_t logicalLength = 0; |
| 303 | + |
| 304 | + switch (to->dsc_dtype) |
| 305 | + { |
| 306 | + case dtype_sql_time_tz: |
| 307 | + logicalLength = offsetof(ISC_TIME_TZ, time_zone) + sizeof(ISC_USHORT); |
| 308 | + break; |
| 309 | + |
| 310 | + case dtype_timestamp_tz: |
| 311 | + logicalLength = offsetof(ISC_TIMESTAMP_TZ, time_zone) + sizeof(ISC_USHORT); |
| 312 | + break; |
| 313 | + |
| 314 | + default: |
| 315 | + return; |
| 316 | + } |
| 317 | + |
| 318 | + if (to->dsc_length > logicalLength) |
| 319 | + memset(to->dsc_address + logicalLength, 0, to->dsc_length - logicalLength); |
| 320 | +} |
| 321 | + |
| 322 | + |
296 | 323 | static void float_to_text(const dsc* from, dsc* to, Callbacks* cb) |
297 | 324 | { |
298 | 325 | /************************************** |
@@ -1680,6 +1707,7 @@ void CVT_move_common(const dsc* from, dsc* to, DecimalStatus decSt, Callbacks* c |
1680 | 1707 | if (length) { |
1681 | 1708 | memcpy(p, q, length); |
1682 | 1709 | } |
| 1710 | + zeroTzPadding(to); |
1683 | 1711 | return; |
1684 | 1712 | } |
1685 | 1713 |
|
@@ -1770,31 +1798,37 @@ void CVT_move_common(const dsc* from, dsc* to, DecimalStatus decSt, Callbacks* c |
1770 | 1798 | CVT_string_to_datetime(from, &date, NULL, expect_timestamp_tz, true, cb); |
1771 | 1799 | *((ISC_TIMESTAMP_TZ*) to->dsc_address) = date; |
1772 | 1800 | } |
| 1801 | + zeroTzPadding(to); |
1773 | 1802 | return; |
1774 | 1803 |
|
1775 | 1804 | case dtype_sql_time: |
1776 | 1805 | *(ISC_TIMESTAMP_TZ*) to->dsc_address = |
1777 | 1806 | TimeZoneUtil::timeToTimeStampTz(*(ISC_TIME*) from->dsc_address, cb); |
| 1807 | + zeroTzPadding(to); |
1778 | 1808 | return; |
1779 | 1809 |
|
1780 | 1810 | case dtype_ex_time_tz: |
1781 | 1811 | case dtype_sql_time_tz: |
1782 | 1812 | *((ISC_TIMESTAMP_TZ*) to->dsc_address) = |
1783 | 1813 | TimeZoneUtil::timeTzToTimeStampTz(*(ISC_TIME_TZ*) from->dsc_address, cb); |
| 1814 | + zeroTzPadding(to); |
1784 | 1815 | return; |
1785 | 1816 |
|
1786 | 1817 | case dtype_ex_timestamp_tz: |
1787 | 1818 | *((ISC_TIMESTAMP_TZ*) to->dsc_address) = *((ISC_TIMESTAMP_TZ*) from->dsc_address); |
| 1819 | + zeroTzPadding(to); |
1788 | 1820 | return; |
1789 | 1821 |
|
1790 | 1822 | case dtype_sql_date: |
1791 | 1823 | *(ISC_TIMESTAMP_TZ*) to->dsc_address = |
1792 | 1824 | TimeZoneUtil::dateToTimeStampTz(*(GDS_DATE*) from->dsc_address, cb); |
| 1825 | + zeroTzPadding(to); |
1793 | 1826 | return; |
1794 | 1827 |
|
1795 | 1828 | case dtype_timestamp: |
1796 | 1829 | *(ISC_TIMESTAMP_TZ*) to->dsc_address = |
1797 | 1830 | TimeZoneUtil::timeStampToTimeStampTz(*(ISC_TIMESTAMP*) from->dsc_address, cb); |
| 1831 | + zeroTzPadding(to); |
1798 | 1832 | return; |
1799 | 1833 |
|
1800 | 1834 | default: |
@@ -1878,26 +1912,31 @@ void CVT_move_common(const dsc* from, dsc* to, DecimalStatus decSt, Callbacks* c |
1878 | 1912 | ((ISC_TIME_TZ*) to->dsc_address)->utc_time = date.utc_timestamp.timestamp_time; |
1879 | 1913 | ((ISC_TIME_TZ*) to->dsc_address)->time_zone = date.time_zone; |
1880 | 1914 | } |
| 1915 | + zeroTzPadding(to); |
1881 | 1916 | return; |
1882 | 1917 |
|
1883 | 1918 | case dtype_sql_time: |
1884 | 1919 | *(ISC_TIME_TZ*) to->dsc_address = TimeZoneUtil::timeToTimeTz(*(ISC_TIME*) from->dsc_address, cb); |
| 1920 | + zeroTzPadding(to); |
1885 | 1921 | return; |
1886 | 1922 |
|
1887 | 1923 | case dtype_timestamp: |
1888 | 1924 | *(ISC_TIME_TZ*) to->dsc_address = |
1889 | 1925 | TimeZoneUtil::timeStampToTimeTz(*(ISC_TIMESTAMP*) from->dsc_address, cb); |
| 1926 | + zeroTzPadding(to); |
1890 | 1927 | return; |
1891 | 1928 |
|
1892 | 1929 | case dtype_timestamp_tz: |
1893 | 1930 | case dtype_ex_timestamp_tz: |
1894 | 1931 | *(ISC_TIME_TZ*) to->dsc_address = |
1895 | 1932 | TimeZoneUtil::timeStampTzToTimeTz(*(ISC_TIMESTAMP_TZ*) from->dsc_address); |
| 1933 | + zeroTzPadding(to); |
1896 | 1934 | return; |
1897 | 1935 |
|
1898 | 1936 | case dtype_ex_time_tz: |
1899 | 1937 | *(ISC_TIME_TZ*) to->dsc_address = *(ISC_TIME_TZ*) from->dsc_address; |
1900 | | - return; |
| 1938 | + zeroTzPadding(to); |
| 1939 | + return; |
1901 | 1940 |
|
1902 | 1941 | default: |
1903 | 1942 | CVT_conversion_error(from, cb->err); |
|
0 commit comments