Skip to content

Commit bfe90be

Browse files
authored
Merge pull request mariadb-corporation#1677 from tntnatbry/MCOL-4177-2
MCOL-4177 Add support for bulk insertion for wide decimals.
2 parents 45197c4 + f6b55c1 commit bfe90be

File tree

9 files changed

+205
-299
lines changed

9 files changed

+205
-299
lines changed

datatypes/mcs_datatype.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ using namespace dataconvert;
5757
namespace datatypes
5858
{
5959

60-
int128_t SystemCatalog::TypeAttributesStd::decimal128FromString(const std::string& value) const
60+
int128_t
61+
SystemCatalog::TypeAttributesStd::decimal128FromString(
62+
const std::string& value, bool *saturate) const
6163
{
6264
int128_t result = 0;
6365
bool pushWarning = false;
@@ -67,7 +69,8 @@ int128_t SystemCatalog::TypeAttributesStd::decimal128FromString(const std::strin
6769
*this,
6870
pushWarning,
6971
noRoundup,
70-
result);
72+
result,
73+
saturate);
7174
return result;
7275
}
7376

datatypes/mcs_datatype.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,15 @@ class SystemCatalog
167167
scale(0),
168168
precision(-1)
169169
{}
170+
TypeAttributesStd(int32_t w, int32_t s, int32_t p)
171+
:colWidth(w),
172+
scale(s),
173+
precision(p)
174+
{}
170175
/**
171176
@brief Convenience method to get int128 from a std::string.
172177
*/
173-
int128_t decimal128FromString(const std::string& value) const;
178+
int128_t decimal128FromString(const std::string& value, bool *saturate = 0) const;
174179

175180
/**
176181
@brief The method sets the legacy scale and precision of a wide decimal

dbcon/mysql/ha_mcs_datatype.h

+30-252
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,20 @@ class StoreFieldMariaDB: public StoreField
188188

189189
class WriteBatchFieldMariaDB: public WriteBatchField
190190
{
191+
// Maximum number of decimal digits that can be represented in 4 bytes
192+
static const int DIG_PER_DEC = 9;
193+
// See strings/decimal.c
194+
const int dig2bytes[DIG_PER_DEC+1]={0, 1, 1, 2, 2, 3, 3, 4, 4, 4};
195+
196+
197+
// Returns the number of bytes required to store a given number
198+
// of decimal digits
199+
int numDecimalBytes(int digits)
200+
{
201+
return (((digits/DIG_PER_DEC) * 4) + dig2bytes[digits % DIG_PER_DEC]);
202+
}
203+
204+
191205
public:
192206
Field *m_field;
193207
const CalpontSystemCatalog::ColType &m_type;
@@ -539,264 +553,28 @@ class WriteBatchFieldMariaDB: public WriteBatchField
539553

540554
size_t ColWriteBatchXDecimal(const uchar *buf, bool nullVal, ColBatchWriter &ci) override
541555
{
542-
uint bytesBefore = 1;
543-
uint totalBytes = 9;
544-
545-
switch (m_type.precision)
546-
{
547-
case 18:
548-
case 17:
549-
case 16:
550-
{
551-
totalBytes = 8;
552-
break;
553-
}
554-
555-
case 15:
556-
case 14:
557-
{
558-
totalBytes = 7;
559-
break;
560-
}
561-
562-
case 13:
563-
case 12:
564-
{
565-
totalBytes = 6;
566-
break;
567-
}
568-
569-
case 11:
570-
{
571-
totalBytes = 5;
572-
break;
573-
}
574-
575-
case 10:
576-
{
577-
totalBytes = 5;
578-
break;
579-
}
580-
581-
case 9:
582-
case 8:
583-
case 7:
584-
{
585-
totalBytes = 4;
586-
break;
587-
}
588-
589-
case 6:
590-
case 5:
591-
{
592-
totalBytes = 3;
593-
break;
594-
}
595-
596-
case 4:
597-
case 3:
598-
{
599-
totalBytes = 2;
600-
break;
601-
}
602-
603-
case 2:
604-
case 1:
605-
{
606-
totalBytes = 1;
607-
break;
608-
}
609-
610-
default:
611-
break;
612-
}
613-
614-
switch (m_type.scale)
615-
{
616-
case 0:
617-
{
618-
bytesBefore = totalBytes;
619-
break;
620-
}
621-
622-
case 1: //1 byte for digits after decimal point
623-
{
624-
if ((m_type.precision != 16) && (m_type.precision != 14)
625-
&& (m_type.precision != 12) && (m_type.precision != 10)
626-
&& (m_type.precision != 7) && (m_type.precision != 5)
627-
&& (m_type.precision != 3) && (m_type.precision != 1))
628-
totalBytes++;
629-
630-
bytesBefore = totalBytes - 1;
631-
break;
632-
}
633-
634-
case 2: //1 byte for digits after decimal point
635-
{
636-
if ((m_type.precision == 18) || (m_type.precision == 9))
637-
totalBytes++;
638-
639-
bytesBefore = totalBytes - 1;
640-
break;
641-
}
642-
643-
case 3: //2 bytes for digits after decimal point
644-
{
645-
if ((m_type.precision != 16) && (m_type.precision != 14)
646-
&& (m_type.precision != 12) && (m_type.precision != 7)
647-
&& (m_type.precision != 5) && (m_type.precision != 3))
648-
totalBytes++;
649-
650-
bytesBefore = totalBytes - 2;
651-
break;
652-
}
653-
654-
case 4:
655-
{
656-
if ((m_type.precision == 18) || (m_type.precision == 11)
657-
|| (m_type.precision == 9))
658-
totalBytes++;
659-
660-
bytesBefore = totalBytes - 2;
661-
break;
662-
663-
}
664-
665-
case 5:
666-
{
667-
if ((m_type.precision != 16) && (m_type.precision != 14)
668-
&& (m_type.precision != 7) && (m_type.precision != 5))
669-
totalBytes++;
670-
671-
bytesBefore = totalBytes - 3;
672-
break;
673-
}
674-
675-
case 6:
676-
{
677-
if ((m_type.precision == 18) || (m_type.precision == 13)
678-
|| (m_type.precision == 11) || (m_type.precision == 9))
679-
totalBytes++;
680-
681-
bytesBefore = totalBytes - 3;
682-
break;
683-
}
684-
685-
case 7:
686-
{
687-
if ((m_type.precision != 16) && (m_type.precision != 7))
688-
totalBytes++;
689-
690-
bytesBefore = totalBytes - 4;
691-
break;
692-
}
693-
694-
case 8:
695-
{
696-
if ((m_type.precision == 18) || (m_type.precision == 15)
697-
|| (m_type.precision == 13) || (m_type.precision == 11)
698-
|| (m_type.precision == 9))
699-
totalBytes++;
700-
701-
bytesBefore = totalBytes - 4;;
702-
break;
703-
}
704-
705-
case 9:
706-
{
707-
bytesBefore = totalBytes - 4;;
708-
break;
709-
}
710-
711-
case 10:
712-
{
713-
if ((m_type.precision != 16) && (m_type.precision != 14)
714-
&& (m_type.precision != 12) && (m_type.precision != 10))
715-
totalBytes++;
716-
717-
bytesBefore = totalBytes - 5;;
718-
break;
719-
}
720-
721-
case 11:
722-
{
723-
if (m_type.precision == 18)
724-
totalBytes++;
725-
726-
bytesBefore = totalBytes - 5;
727-
break;
728-
}
729-
730-
case 12:
731-
{
732-
if ((m_type.precision != 16) && (m_type.precision != 14)
733-
&& (m_type.precision != 12))
734-
totalBytes++;
735-
736-
bytesBefore = totalBytes - 6;
737-
break;
738-
}
739-
740-
case 13:
741-
{
742-
if (m_type.precision == 18)
743-
totalBytes++;
744-
745-
bytesBefore = totalBytes - 6;
746-
break;
747-
}
748-
749-
case 14:
750-
{
751-
if ((m_type.precision != 16) && (m_type.precision != 14))
752-
totalBytes++;
753-
754-
bytesBefore = totalBytes - 7;
755-
break;
756-
}
757-
758-
case 15:
759-
{
760-
if (m_type.precision == 18)
761-
totalBytes++;
762-
763-
bytesBefore = totalBytes - 7;
764-
break;
765-
}
766-
767-
case 16:
768-
{
769-
if (m_type.precision != 16)
770-
totalBytes++;
771-
772-
bytesBefore = totalBytes - 8;
773-
break;
774-
}
775-
776-
case 17:
777-
{
778-
if (m_type.precision == 18)
779-
totalBytes++;
780-
781-
bytesBefore = totalBytes - 8;
782-
break;
783-
}
784-
785-
case 18:
786-
{
787-
bytesBefore = totalBytes - 8;
788-
break;
789-
}
790-
791-
default:
792-
break;
793-
}
556+
uint bytesBefore = numDecimalBytes(m_type.precision - m_type.scale);
557+
uint totalBytes = bytesBefore + numDecimalBytes(m_type.scale);
794558

795559
if (nullVal && (m_type.constraintType != CalpontSystemCatalog::NOTNULL_CONSTRAINT))
796560
{
797561
fprintf(ci.filePtr(), "%c", ci.delimiter());
798562
//printf("|");
799563
}
564+
else if (m_type.precision > datatypes::INT64MAXPRECISION)
565+
{
566+
// TODO MCOL-641 The below else block for narrow decimal
567+
// i.e. (m_type.precision <= datatypes::INT64MAXPRECISION)
568+
// converts the decimal binary representation in buf directly
569+
// to a string, while here, the my_decimal ctor first calls
570+
// bin2decimal() on buf, and then we construct the string from
571+
// the my_decimal. This approach might be a bit slower than the
572+
// narrow decimal approach.
573+
my_decimal dec(buf, m_type.precision, m_type.scale);
574+
String str;
575+
dec.to_string(&str);
576+
fprintf(ci.filePtr(), "%s%c", str.c_ptr(), ci.delimiter());
577+
}
800578
else
801579
{
802580
uint32_t mask [5] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF};

0 commit comments

Comments
 (0)