Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH v1 1/1] sql: remove unused serialization functions
@ 2021-01-28 11:49 Mergen Imeev via Tarantool-patches
  2021-02-01 15:40 ` Nikita Pettik via Tarantool-patches
  2021-02-02  7:57 ` Kirill Yukhin via Tarantool-patches
  0 siblings, 2 replies; 5+ messages in thread
From: Mergen Imeev via Tarantool-patches @ 2021-01-28 11:49 UTC (permalink / raw)
  To: korablev; +Cc: tarantool-patches

This patch removes serialization functions that are not used in Tarantool.

Part of #4470
---
https://github.com/tarantool/tarantool/issues/4470
https://github.com/tarantool/tarantool/tree/imeevma/gh-4470-remove-unused-serialization-functions

 src/box/sql/vdbe.c    |   5 +-
 src/box/sql/vdbeInt.h |   4 -
 src/box/sql/vdbeaux.c | 407 ------------------------------------------
 3 files changed, 2 insertions(+), 414 deletions(-)

diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 1707c216e..3b3b1f01d 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -2922,9 +2922,8 @@ case OP_MakeRecord: {
 	 * and so forth.
 	 *
 	 * Each type field is a varint representing the serial type of the
-	 * corresponding data element (see sqlVdbeSerialType()). The
-	 * hdr-size field is also a varint which is the offset from the beginning
-	 * of the record to data0.
+	 * corresponding data element. The hdr-size field is also a varint which
+	 * is the offset from the beginning of the record to data0.
 	 */
 	nField = pOp->p1;
 	enum field_type *types = pOp->p4.types;
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index ad46ab129..7205f1af3 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -472,10 +472,6 @@ int sqlVdbeCursorRestore(VdbeCursor *);
 #if defined(SQL_DEBUG) || defined(VDBE_PROFILE)
 void sqlVdbePrintOp(FILE *, int, Op *);
 #endif
-u32 sqlVdbeSerialTypeLen(u32);
-u32 sqlVdbeSerialType(Mem *, int, u32 *);
-u32 sqlVdbeSerialPut(unsigned char *, Mem *, u32);
-u32 sqlVdbeSerialGet(const unsigned char *, u32, Mem *);
 
 int sqlVdbeExec(Vdbe *);
 int sqlVdbeList(Vdbe *);
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index bae1a5352..91b64316e 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -2303,413 +2303,6 @@ sqlVdbeDelete(Vdbe * p)
 	sqlDbFree(db, p);
 }
 
-/*
- * The following functions:
- *
- * sqlVdbeSerialType()
- * sqlVdbeSerialTypeLen()
- * sqlVdbeSerialLen()
- * sqlVdbeSerialPut()
- * sqlVdbeSerialGet()
- *
- * encapsulate the code that serializes values for storage in sql
- * data and index records. Each serialized value consists of a
- * 'serial-type' and a blob of data. The serial type is an 8-byte unsigned
- * integer, stored as a varint.
- *
- * In an sql index record, the serial type is stored directly before
- * the blob of data that it corresponds to. In a table record, all serial
- * types are stored at the start of the record, and the blobs of data at
- * the end. Hence these functions allow the caller to handle the
- * serial-type and data blob separately.
- *
- * The following table describes the various storage classes for data:
- *
- *   serial type        bytes of data      type
- *   --------------     ---------------    ---------------
- *      0                     0            NULL
- *      1                     1            signed integer
- *      2                     2            signed integer
- *      3                     3            signed integer
- *      4                     4            signed integer
- *      5                     6            signed integer
- *      6                     8            signed integer
- *      7                     8            IEEE float
- *      8                     0            Integer constant 0
- *      9                     0            Integer constant 1
- *     10,11                               reserved for expansion
- *    N>=12 and even       (N-12)/2        BLOB
- *    N>=13 and odd        (N-13)/2        text
- *
- * The 8 and 9 types were added in 3.3.0, file format 4.  Prior versions
- * of sql will not understand those serial types.
- */
-
-/*
- * Return the serial-type for the value stored in pMem.
- */
-u32
-sqlVdbeSerialType(Mem * pMem, int file_format, u32 * pLen)
-{
-	int flags = pMem->flags;
-	u32 n;
-
-	assert(pLen != 0);
-	if (flags & MEM_Null) {
-		*pLen = 0;
-		return 0;
-	}
-	if (flags & MEM_Int) {
-		/* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
-#define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
-		i64 i = pMem->u.i;
-		u64 u;
-		if (i < 0) {
-			u = ~i;
-		} else {
-			u = i;
-		}
-		if (u <= 127) {
-			if ((i & 1) == i && file_format >= 4) {
-				*pLen = 0;
-				return 8 + (u32) u;
-			} else {
-				*pLen = 1;
-				return 1;
-			}
-		}
-		if (u <= 32767) {
-			*pLen = 2;
-			return 2;
-		}
-		if (u <= 8388607) {
-			*pLen = 3;
-			return 3;
-		}
-		if (u <= 2147483647) {
-			*pLen = 4;
-			return 4;
-		}
-		if (u <= MAX_6BYTE) {
-			*pLen = 6;
-			return 5;
-		}
-		*pLen = 8;
-		return 6;
-	}
-	if (flags & MEM_Real) {
-		*pLen = 8;
-		return 7;
-	}
-	assert(pMem->db->mallocFailed || flags & (MEM_Str | MEM_Blob));
-	assert(pMem->n >= 0);
-	n = (u32) pMem->n;
-	if (flags & MEM_Zero) {
-		n += pMem->u.nZero;
-	}
-	*pLen = n;
-	return ((n * 2) + 12 + ((flags & MEM_Str) != 0));
-}
-
-/*
- * The sizes for serial types less than 128
- */
-static const u8 sqlSmallTypeSizes[] = {
-	/*  0   1   2   3   4   5   6   7   8   9 */
-/*   0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0,
-/*  10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
-/*  20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
-/*  30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
-/*  40 */ 14, 14, 15, 15, 16, 16, 17, 17, 18, 18,
-/*  50 */ 19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
-/*  60 */ 24, 24, 25, 25, 26, 26, 27, 27, 28, 28,
-/*  70 */ 29, 29, 30, 30, 31, 31, 32, 32, 33, 33,
-/*  80 */ 34, 34, 35, 35, 36, 36, 37, 37, 38, 38,
-/*  90 */ 39, 39, 40, 40, 41, 41, 42, 42, 43, 43,
-/* 100 */ 44, 44, 45, 45, 46, 46, 47, 47, 48, 48,
-/* 110 */ 49, 49, 50, 50, 51, 51, 52, 52, 53, 53,
-/* 120 */ 54, 54, 55, 55, 56, 56, 57, 57
-};
-
-/*
- * Return the length of the data corresponding to the supplied serial-type.
- */
-u32
-sqlVdbeSerialTypeLen(u32 serial_type)
-{
-	if (serial_type >= 128) {
-		return (serial_type - 12) / 2;
-	} else {
-		assert(serial_type < 12
-		       || sqlSmallTypeSizes[serial_type] ==
-		       (serial_type - 12) / 2);
-		return sqlSmallTypeSizes[serial_type];
-	}
-}
-
-/*
- * If we are on an architecture with mixed-endian floating
- * points (ex: ARM7) then swap the lower 4 bytes with the
- * upper 4 bytes.  Return the result.
- *
- * For most architectures, this is a no-op.
- *
- * (later):  It is reported to me that the mixed-endian problem
- * on ARM7 is an issue with GCC, not with the ARM7 chip.  It seems
- * that early versions of GCC stored the two words of a 64-bit
- * float in the wrong order.  And that error has been propagated
- * ever since.  The blame is not necessarily with GCC, though.
- * GCC might have just copying the problem from a prior compiler.
- * I am also told that newer versions of GCC that follow a different
- * ABI get the byte order right.
- *
- * Developers using sql on an ARM7 should compile and run their
- * application using -DSQL_DEBUG=1 at least once.  With DEBUG
- * enabled, some asserts below will ensure that the byte order of
- * floating point values is correct.
- *
- * (2007-08-30)  Frank van Vugt has studied this problem closely
- * and has send his findings to the sql developers.  Frank
- * writes that some Linux kernels offer floating point hardware
- * emulation that uses only 32-bit mantissas instead of a full
- * 48-bits as required by the IEEE standard.  (This is the
- * CONFIG_FPE_FASTFPE option.)  On such systems, floating point
- * byte swapping becomes very complicated.  To avoid problems,
- * the necessary byte swapping is carried out using a 64-bit integer
- * rather than a 64-bit float.  Frank assures us that the code here
- * works for him.  We, the developers, have no way to independently
- * verify this, but Frank seems to know what he is talking about
- * so we trust him.
- */
-#ifdef SQL_MIXED_ENDIAN_64BIT_FLOAT
-static u64
-floatSwap(u64 in)
-{
-	union {
-		u64 r;
-		u32 i[2];
-	} u;
-	u32 t;
-
-	u.r = in;
-	t = u.i[0];
-	u.i[0] = u.i[1];
-	u.i[1] = t;
-	return u.r;
-}
-
-#define swapMixedEndianFloat(X)  X = floatSwap(X)
-#else
-#define swapMixedEndianFloat(X)
-#endif
-
-/*
- * Write the serialized data blob for the value stored in pMem into
- * buf. It is assumed that the caller has allocated sufficient space.
- * Return the number of bytes written.
- *
- * nBuf is the amount of space left in buf[].  The caller is responsible
- * for allocating enough space to buf[] to hold the entire field, exclusive
- * of the pMem->u.nZero bytes for a MEM_Zero value.
- *
- * Return the number of bytes actually written into buf[].  The number
- * of bytes in the zero-filled tail is included in the return value only
- * if those bytes were zeroed in buf[].
- */
-u32
-sqlVdbeSerialPut(u8 * buf, Mem * pMem, u32 serial_type)
-{
-	u32 len;
-
-	/* Integer and Real */
-	if (serial_type <= 7 && serial_type > 0) {
-		u64 v;
-		u32 i;
-		if (serial_type == 7) {
-			assert(sizeof(v) == sizeof(pMem->u.r));
-			memcpy(&v, &pMem->u.r, sizeof(v));
-			swapMixedEndianFloat(v);
-		} else {
-			v = pMem->u.i;
-		}
-		len = i = sqlSmallTypeSizes[serial_type];
-		assert(i > 0);
-		do {
-			buf[--i] = (u8) (v & 0xFF);
-			v >>= 8;
-		} while (i);
-		return len;
-	}
-
-	/* String or blob */
-	if (serial_type >= 12) {
-		assert(pMem->n + ((pMem->flags & MEM_Zero) ? pMem->u.nZero : 0)
-		       == (int)sqlVdbeSerialTypeLen(serial_type));
-		len = pMem->n;
-		if (len > 0)
-			memcpy(buf, pMem->z, len);
-		return len;
-	}
-
-	/* NULL or constants 0 or 1 */
-	return 0;
-}
-
-/* Input "x" is a sequence of unsigned characters that represent a
- * big-endian integer.  Return the equivalent native integer
- */
-#define ONE_BYTE_INT(x)    ((i8)(x)[0])
-#define TWO_BYTE_INT(x)    (256*(i8)((x)[0])|(x)[1])
-#define THREE_BYTE_INT(x)  (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2])
-#define FOUR_BYTE_UINT(x)  (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
-#define FOUR_BYTE_INT(x) (16777216*(i8)((x)[0])|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
-
-/*
- * Deserialize the data blob pointed to by buf as serial type serial_type
- * and store the result in pMem.  Return the number of bytes read.
- *
- * This function is implemented as two separate routines for performance.
- * The few cases that require local variables are broken out into a separate
- * routine so that in most cases the overhead of moving the stack pointer
- * is avoided.
- */
-static u32 SQL_NOINLINE
-serialGet(const unsigned char *buf,	/* Buffer to deserialize from */
-	  u32 serial_type,		/* Serial type to deserialize */
-	  Mem * pMem)			/* Memory cell to write value into */
-{
-	u64 x = FOUR_BYTE_UINT(buf);
-	u32 y = FOUR_BYTE_UINT(buf + 4);
-	x = (x << 32) + y;
-	if (serial_type == 6) {
-		/* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit
-		 * twos-complement integer.
-		 */
-		pMem->u.i = *(i64 *) & x;
-		pMem->flags = MEM_Int;
-		testcase(pMem->u.i < 0);
-	} else {
-		/* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit
-		 * floating point number.
-		 */
-#if !defined(NDEBUG)
-		/* Verify that integers and floating point values use the same
-		 * byte order.  Or, that if SQL_MIXED_ENDIAN_64BIT_FLOAT is
-		 * defined that 64-bit floating point values really are mixed
-		 * endian.
-		 */
-		static const u64 t1 = ((u64) 0x3ff00000) << 32;
-		static const double r1 = 1.0;
-		u64 t2 = t1;
-		swapMixedEndianFloat(t2);
-		assert(sizeof(r1) == sizeof(t2)
-		       && memcmp(&r1, &t2, sizeof(r1)) == 0);
-#endif
-		assert(sizeof(x) == 8 && sizeof(pMem->u.r) == 8);
-		swapMixedEndianFloat(x);
-		memcpy(&pMem->u.r, &x, sizeof(x));
-		pMem->flags = sqlIsNaN(pMem->u.r) ? MEM_Null : MEM_Real;
-	}
-	return 8;
-}
-
-u32
-sqlVdbeSerialGet(const unsigned char *buf,	/* Buffer to deserialize from */
-		     u32 serial_type,		/* Serial type to deserialize */
-		     Mem * pMem)		/* Memory cell to write value into */
-{
-	switch (serial_type) {
-	case 10:		/* Reserved for future use */
-	case 11:		/* Reserved for future use */
-	case 0:{		/* Null */
-			/* EVIDENCE-OF: R-24078-09375 Value is a NULL. */
-			pMem->flags = MEM_Null;
-			break;
-		}
-	case 1:{
-			/* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement
-			 * integer.
-			 */
-			pMem->u.i = ONE_BYTE_INT(buf);
-			pMem->flags = MEM_Int;
-			testcase(pMem->u.i < 0);
-			return 1;
-		}
-	case 2:{		/* 2-byte signed integer */
-			/* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit
-			 * twos-complement integer.
-			 */
-			pMem->u.i = TWO_BYTE_INT(buf);
-			pMem->flags = MEM_Int;
-			testcase(pMem->u.i < 0);
-			return 2;
-		}
-	case 3:{		/* 3-byte signed integer */
-			/* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit
-			 * twos-complement integer.
-			 */
-			pMem->u.i = THREE_BYTE_INT(buf);
-			pMem->flags = MEM_Int;
-			testcase(pMem->u.i < 0);
-			return 3;
-		}
-	case 4:{		/* 4-byte signed integer */
-			/* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit
-			 * twos-complement integer.
-			 */
-			pMem->u.i = FOUR_BYTE_INT(buf);
-#ifdef __HP_cc
-			/* Work around a sign-extension bug in the HP compiler for HP/UX */
-			if (buf[0] & 0x80)
-				pMem->u.i |= 0xffffffff80000000LL;
-#endif
-			pMem->flags = MEM_Int;
-			testcase(pMem->u.i < 0);
-			return 4;
-		}
-	case 5:{		/* 6-byte signed integer */
-			/* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit
-			 * twos-complement integer.
-			 */
-			pMem->u.i =
-			    FOUR_BYTE_UINT(buf + 2) +
-			    (((i64) 1) << 32) * TWO_BYTE_INT(buf);
-			pMem->flags = MEM_Int;
-			testcase(pMem->u.i < 0);
-			return 6;
-		}
-	case 6:		/* 8-byte signed integer */
-	case 7:{		/* IEEE floating point */
-			/* These use local variables, so do them in a separate routine
-			 * to avoid having to move the frame pointer in the common case
-			 */
-			return serialGet(buf, serial_type, pMem);
-		}
-	case 8:		/* Integer 0 */
-	case 9:{		/* Integer 1 */
-			/* EVIDENCE-OF: R-12976-22893 Value is the integer 0. */
-			/* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */
-			pMem->u.i = serial_type - 8;
-			pMem->flags = MEM_Int;
-			return 0;
-		}
-	default:{
-			/* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in
-			 * length.
-			 * EVIDENCE-OF: R-28401-00140 Value is a string in the text encoding and
-			 * (N-13)/2 bytes in length.
-			 */
-			static const u16 aFlag[] =
-			    { MEM_Blob | MEM_Ephem, MEM_Str | MEM_Ephem };
-			pMem->z = (char *)buf;
-			pMem->n = (serial_type - 12) / 2;
-			pMem->flags = aFlag[serial_type & 1];
-			return pMem->n;
-		}
-	}
-	return 0;
-}
-
 /*
  * This routine is used to allocate sufficient space for an UnpackedRecord
  * structure large enough to be used with sqlVdbeRecordUnpack() if
-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Tarantool-patches] [PATCH v1 1/1] sql: remove unused serialization functions
  2021-01-28 11:49 [Tarantool-patches] [PATCH v1 1/1] sql: remove unused serialization functions Mergen Imeev via Tarantool-patches
@ 2021-02-01 15:40 ` Nikita Pettik via Tarantool-patches
  2021-02-02  7:57 ` Kirill Yukhin via Tarantool-patches
  1 sibling, 0 replies; 5+ messages in thread
From: Nikita Pettik via Tarantool-patches @ 2021-02-01 15:40 UTC (permalink / raw)
  To: imeevma; +Cc: tarantool-patches

On 28 Jan 14:49, imeevma@tarantool.org wrote:
> This patch removes serialization functions that are not used in Tarantool.
> 
> Part of #4470

IDK how it is related to 4470 but lgtm.

> ---
> https://github.com/tarantool/tarantool/issues/4470
> https://github.com/tarantool/tarantool/tree/imeevma/gh-4470-remove-unused-serialization-functions
> 
>  src/box/sql/vdbe.c    |   5 +-
>  src/box/sql/vdbeInt.h |   4 -
>  src/box/sql/vdbeaux.c | 407 ------------------------------------------
>  3 files changed, 2 insertions(+), 414 deletions(-)
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Tarantool-patches] [PATCH v1 1/1] sql: remove unused serialization functions
  2021-01-28 11:49 [Tarantool-patches] [PATCH v1 1/1] sql: remove unused serialization functions Mergen Imeev via Tarantool-patches
  2021-02-01 15:40 ` Nikita Pettik via Tarantool-patches
@ 2021-02-02  7:57 ` Kirill Yukhin via Tarantool-patches
  1 sibling, 0 replies; 5+ messages in thread
From: Kirill Yukhin via Tarantool-patches @ 2021-02-02  7:57 UTC (permalink / raw)
  To: imeevma; +Cc: tarantool-patches

Hello,

On 28 янв 14:49, Mergen Imeev via Tarantool-patches wrote:
> This patch removes serialization functions that are not used in Tarantool.
> 

> Part of #4470

I've dropped that.

LGTM.

I've checked your patch into master.

--
Regards, Kirill Yukhin

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Tarantool-patches] [PATCH v1 1/1] sql: remove unused serialization functions
  2021-01-22 13:21 Mergen Imeev via Tarantool-patches
@ 2021-01-27 22:28 ` Vladislav Shpilevoy via Tarantool-patches
  0 siblings, 0 replies; 5+ messages in thread
From: Vladislav Shpilevoy via Tarantool-patches @ 2021-01-27 22:28 UTC (permalink / raw)
  To: imeevma; +Cc: tarantool-patches

Hi! Thanks for the patch!

LGTM.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Tarantool-patches] [PATCH v1 1/1] sql: remove unused serialization functions
@ 2021-01-22 13:21 Mergen Imeev via Tarantool-patches
  2021-01-27 22:28 ` Vladislav Shpilevoy via Tarantool-patches
  0 siblings, 1 reply; 5+ messages in thread
From: Mergen Imeev via Tarantool-patches @ 2021-01-22 13:21 UTC (permalink / raw)
  To: v.shpilevoy; +Cc: tarantool-patches

This patch removes serialization functions that are not used in Tarantool.

Part of #4470
---
https://github.com/tarantool/tarantool/issues/4470
https://github.com/tarantool/tarantool/tree/imeevma/gh-4470-remove-unused-serialization-functions

 src/box/sql/vdbe.c    |   5 +-
 src/box/sql/vdbeInt.h |   4 -
 src/box/sql/vdbeaux.c | 407 ------------------------------------------
 3 files changed, 2 insertions(+), 414 deletions(-)

diff --git a/src/box/sql/vdbe.c b/src/box/sql/vdbe.c
index 1707c216e..3b3b1f01d 100644
--- a/src/box/sql/vdbe.c
+++ b/src/box/sql/vdbe.c
@@ -2922,9 +2922,8 @@ case OP_MakeRecord: {
 	 * and so forth.
 	 *
 	 * Each type field is a varint representing the serial type of the
-	 * corresponding data element (see sqlVdbeSerialType()). The
-	 * hdr-size field is also a varint which is the offset from the beginning
-	 * of the record to data0.
+	 * corresponding data element. The hdr-size field is also a varint which
+	 * is the offset from the beginning of the record to data0.
 	 */
 	nField = pOp->p1;
 	enum field_type *types = pOp->p4.types;
diff --git a/src/box/sql/vdbeInt.h b/src/box/sql/vdbeInt.h
index ad46ab129..7205f1af3 100644
--- a/src/box/sql/vdbeInt.h
+++ b/src/box/sql/vdbeInt.h
@@ -472,10 +472,6 @@ int sqlVdbeCursorRestore(VdbeCursor *);
 #if defined(SQL_DEBUG) || defined(VDBE_PROFILE)
 void sqlVdbePrintOp(FILE *, int, Op *);
 #endif
-u32 sqlVdbeSerialTypeLen(u32);
-u32 sqlVdbeSerialType(Mem *, int, u32 *);
-u32 sqlVdbeSerialPut(unsigned char *, Mem *, u32);
-u32 sqlVdbeSerialGet(const unsigned char *, u32, Mem *);
 
 int sqlVdbeExec(Vdbe *);
 int sqlVdbeList(Vdbe *);
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index bae1a5352..91b64316e 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -2303,413 +2303,6 @@ sqlVdbeDelete(Vdbe * p)
 	sqlDbFree(db, p);
 }
 
-/*
- * The following functions:
- *
- * sqlVdbeSerialType()
- * sqlVdbeSerialTypeLen()
- * sqlVdbeSerialLen()
- * sqlVdbeSerialPut()
- * sqlVdbeSerialGet()
- *
- * encapsulate the code that serializes values for storage in sql
- * data and index records. Each serialized value consists of a
- * 'serial-type' and a blob of data. The serial type is an 8-byte unsigned
- * integer, stored as a varint.
- *
- * In an sql index record, the serial type is stored directly before
- * the blob of data that it corresponds to. In a table record, all serial
- * types are stored at the start of the record, and the blobs of data at
- * the end. Hence these functions allow the caller to handle the
- * serial-type and data blob separately.
- *
- * The following table describes the various storage classes for data:
- *
- *   serial type        bytes of data      type
- *   --------------     ---------------    ---------------
- *      0                     0            NULL
- *      1                     1            signed integer
- *      2                     2            signed integer
- *      3                     3            signed integer
- *      4                     4            signed integer
- *      5                     6            signed integer
- *      6                     8            signed integer
- *      7                     8            IEEE float
- *      8                     0            Integer constant 0
- *      9                     0            Integer constant 1
- *     10,11                               reserved for expansion
- *    N>=12 and even       (N-12)/2        BLOB
- *    N>=13 and odd        (N-13)/2        text
- *
- * The 8 and 9 types were added in 3.3.0, file format 4.  Prior versions
- * of sql will not understand those serial types.
- */
-
-/*
- * Return the serial-type for the value stored in pMem.
- */
-u32
-sqlVdbeSerialType(Mem * pMem, int file_format, u32 * pLen)
-{
-	int flags = pMem->flags;
-	u32 n;
-
-	assert(pLen != 0);
-	if (flags & MEM_Null) {
-		*pLen = 0;
-		return 0;
-	}
-	if (flags & MEM_Int) {
-		/* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
-#define MAX_6BYTE ((((i64)0x00008000)<<32)-1)
-		i64 i = pMem->u.i;
-		u64 u;
-		if (i < 0) {
-			u = ~i;
-		} else {
-			u = i;
-		}
-		if (u <= 127) {
-			if ((i & 1) == i && file_format >= 4) {
-				*pLen = 0;
-				return 8 + (u32) u;
-			} else {
-				*pLen = 1;
-				return 1;
-			}
-		}
-		if (u <= 32767) {
-			*pLen = 2;
-			return 2;
-		}
-		if (u <= 8388607) {
-			*pLen = 3;
-			return 3;
-		}
-		if (u <= 2147483647) {
-			*pLen = 4;
-			return 4;
-		}
-		if (u <= MAX_6BYTE) {
-			*pLen = 6;
-			return 5;
-		}
-		*pLen = 8;
-		return 6;
-	}
-	if (flags & MEM_Real) {
-		*pLen = 8;
-		return 7;
-	}
-	assert(pMem->db->mallocFailed || flags & (MEM_Str | MEM_Blob));
-	assert(pMem->n >= 0);
-	n = (u32) pMem->n;
-	if (flags & MEM_Zero) {
-		n += pMem->u.nZero;
-	}
-	*pLen = n;
-	return ((n * 2) + 12 + ((flags & MEM_Str) != 0));
-}
-
-/*
- * The sizes for serial types less than 128
- */
-static const u8 sqlSmallTypeSizes[] = {
-	/*  0   1   2   3   4   5   6   7   8   9 */
-/*   0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0,
-/*  10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
-/*  20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
-/*  30 */ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
-/*  40 */ 14, 14, 15, 15, 16, 16, 17, 17, 18, 18,
-/*  50 */ 19, 19, 20, 20, 21, 21, 22, 22, 23, 23,
-/*  60 */ 24, 24, 25, 25, 26, 26, 27, 27, 28, 28,
-/*  70 */ 29, 29, 30, 30, 31, 31, 32, 32, 33, 33,
-/*  80 */ 34, 34, 35, 35, 36, 36, 37, 37, 38, 38,
-/*  90 */ 39, 39, 40, 40, 41, 41, 42, 42, 43, 43,
-/* 100 */ 44, 44, 45, 45, 46, 46, 47, 47, 48, 48,
-/* 110 */ 49, 49, 50, 50, 51, 51, 52, 52, 53, 53,
-/* 120 */ 54, 54, 55, 55, 56, 56, 57, 57
-};
-
-/*
- * Return the length of the data corresponding to the supplied serial-type.
- */
-u32
-sqlVdbeSerialTypeLen(u32 serial_type)
-{
-	if (serial_type >= 128) {
-		return (serial_type - 12) / 2;
-	} else {
-		assert(serial_type < 12
-		       || sqlSmallTypeSizes[serial_type] ==
-		       (serial_type - 12) / 2);
-		return sqlSmallTypeSizes[serial_type];
-	}
-}
-
-/*
- * If we are on an architecture with mixed-endian floating
- * points (ex: ARM7) then swap the lower 4 bytes with the
- * upper 4 bytes.  Return the result.
- *
- * For most architectures, this is a no-op.
- *
- * (later):  It is reported to me that the mixed-endian problem
- * on ARM7 is an issue with GCC, not with the ARM7 chip.  It seems
- * that early versions of GCC stored the two words of a 64-bit
- * float in the wrong order.  And that error has been propagated
- * ever since.  The blame is not necessarily with GCC, though.
- * GCC might have just copying the problem from a prior compiler.
- * I am also told that newer versions of GCC that follow a different
- * ABI get the byte order right.
- *
- * Developers using sql on an ARM7 should compile and run their
- * application using -DSQL_DEBUG=1 at least once.  With DEBUG
- * enabled, some asserts below will ensure that the byte order of
- * floating point values is correct.
- *
- * (2007-08-30)  Frank van Vugt has studied this problem closely
- * and has send his findings to the sql developers.  Frank
- * writes that some Linux kernels offer floating point hardware
- * emulation that uses only 32-bit mantissas instead of a full
- * 48-bits as required by the IEEE standard.  (This is the
- * CONFIG_FPE_FASTFPE option.)  On such systems, floating point
- * byte swapping becomes very complicated.  To avoid problems,
- * the necessary byte swapping is carried out using a 64-bit integer
- * rather than a 64-bit float.  Frank assures us that the code here
- * works for him.  We, the developers, have no way to independently
- * verify this, but Frank seems to know what he is talking about
- * so we trust him.
- */
-#ifdef SQL_MIXED_ENDIAN_64BIT_FLOAT
-static u64
-floatSwap(u64 in)
-{
-	union {
-		u64 r;
-		u32 i[2];
-	} u;
-	u32 t;
-
-	u.r = in;
-	t = u.i[0];
-	u.i[0] = u.i[1];
-	u.i[1] = t;
-	return u.r;
-}
-
-#define swapMixedEndianFloat(X)  X = floatSwap(X)
-#else
-#define swapMixedEndianFloat(X)
-#endif
-
-/*
- * Write the serialized data blob for the value stored in pMem into
- * buf. It is assumed that the caller has allocated sufficient space.
- * Return the number of bytes written.
- *
- * nBuf is the amount of space left in buf[].  The caller is responsible
- * for allocating enough space to buf[] to hold the entire field, exclusive
- * of the pMem->u.nZero bytes for a MEM_Zero value.
- *
- * Return the number of bytes actually written into buf[].  The number
- * of bytes in the zero-filled tail is included in the return value only
- * if those bytes were zeroed in buf[].
- */
-u32
-sqlVdbeSerialPut(u8 * buf, Mem * pMem, u32 serial_type)
-{
-	u32 len;
-
-	/* Integer and Real */
-	if (serial_type <= 7 && serial_type > 0) {
-		u64 v;
-		u32 i;
-		if (serial_type == 7) {
-			assert(sizeof(v) == sizeof(pMem->u.r));
-			memcpy(&v, &pMem->u.r, sizeof(v));
-			swapMixedEndianFloat(v);
-		} else {
-			v = pMem->u.i;
-		}
-		len = i = sqlSmallTypeSizes[serial_type];
-		assert(i > 0);
-		do {
-			buf[--i] = (u8) (v & 0xFF);
-			v >>= 8;
-		} while (i);
-		return len;
-	}
-
-	/* String or blob */
-	if (serial_type >= 12) {
-		assert(pMem->n + ((pMem->flags & MEM_Zero) ? pMem->u.nZero : 0)
-		       == (int)sqlVdbeSerialTypeLen(serial_type));
-		len = pMem->n;
-		if (len > 0)
-			memcpy(buf, pMem->z, len);
-		return len;
-	}
-
-	/* NULL or constants 0 or 1 */
-	return 0;
-}
-
-/* Input "x" is a sequence of unsigned characters that represent a
- * big-endian integer.  Return the equivalent native integer
- */
-#define ONE_BYTE_INT(x)    ((i8)(x)[0])
-#define TWO_BYTE_INT(x)    (256*(i8)((x)[0])|(x)[1])
-#define THREE_BYTE_INT(x)  (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2])
-#define FOUR_BYTE_UINT(x)  (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
-#define FOUR_BYTE_INT(x) (16777216*(i8)((x)[0])|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
-
-/*
- * Deserialize the data blob pointed to by buf as serial type serial_type
- * and store the result in pMem.  Return the number of bytes read.
- *
- * This function is implemented as two separate routines for performance.
- * The few cases that require local variables are broken out into a separate
- * routine so that in most cases the overhead of moving the stack pointer
- * is avoided.
- */
-static u32 SQL_NOINLINE
-serialGet(const unsigned char *buf,	/* Buffer to deserialize from */
-	  u32 serial_type,		/* Serial type to deserialize */
-	  Mem * pMem)			/* Memory cell to write value into */
-{
-	u64 x = FOUR_BYTE_UINT(buf);
-	u32 y = FOUR_BYTE_UINT(buf + 4);
-	x = (x << 32) + y;
-	if (serial_type == 6) {
-		/* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit
-		 * twos-complement integer.
-		 */
-		pMem->u.i = *(i64 *) & x;
-		pMem->flags = MEM_Int;
-		testcase(pMem->u.i < 0);
-	} else {
-		/* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit
-		 * floating point number.
-		 */
-#if !defined(NDEBUG)
-		/* Verify that integers and floating point values use the same
-		 * byte order.  Or, that if SQL_MIXED_ENDIAN_64BIT_FLOAT is
-		 * defined that 64-bit floating point values really are mixed
-		 * endian.
-		 */
-		static const u64 t1 = ((u64) 0x3ff00000) << 32;
-		static const double r1 = 1.0;
-		u64 t2 = t1;
-		swapMixedEndianFloat(t2);
-		assert(sizeof(r1) == sizeof(t2)
-		       && memcmp(&r1, &t2, sizeof(r1)) == 0);
-#endif
-		assert(sizeof(x) == 8 && sizeof(pMem->u.r) == 8);
-		swapMixedEndianFloat(x);
-		memcpy(&pMem->u.r, &x, sizeof(x));
-		pMem->flags = sqlIsNaN(pMem->u.r) ? MEM_Null : MEM_Real;
-	}
-	return 8;
-}
-
-u32
-sqlVdbeSerialGet(const unsigned char *buf,	/* Buffer to deserialize from */
-		     u32 serial_type,		/* Serial type to deserialize */
-		     Mem * pMem)		/* Memory cell to write value into */
-{
-	switch (serial_type) {
-	case 10:		/* Reserved for future use */
-	case 11:		/* Reserved for future use */
-	case 0:{		/* Null */
-			/* EVIDENCE-OF: R-24078-09375 Value is a NULL. */
-			pMem->flags = MEM_Null;
-			break;
-		}
-	case 1:{
-			/* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement
-			 * integer.
-			 */
-			pMem->u.i = ONE_BYTE_INT(buf);
-			pMem->flags = MEM_Int;
-			testcase(pMem->u.i < 0);
-			return 1;
-		}
-	case 2:{		/* 2-byte signed integer */
-			/* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit
-			 * twos-complement integer.
-			 */
-			pMem->u.i = TWO_BYTE_INT(buf);
-			pMem->flags = MEM_Int;
-			testcase(pMem->u.i < 0);
-			return 2;
-		}
-	case 3:{		/* 3-byte signed integer */
-			/* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit
-			 * twos-complement integer.
-			 */
-			pMem->u.i = THREE_BYTE_INT(buf);
-			pMem->flags = MEM_Int;
-			testcase(pMem->u.i < 0);
-			return 3;
-		}
-	case 4:{		/* 4-byte signed integer */
-			/* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit
-			 * twos-complement integer.
-			 */
-			pMem->u.i = FOUR_BYTE_INT(buf);
-#ifdef __HP_cc
-			/* Work around a sign-extension bug in the HP compiler for HP/UX */
-			if (buf[0] & 0x80)
-				pMem->u.i |= 0xffffffff80000000LL;
-#endif
-			pMem->flags = MEM_Int;
-			testcase(pMem->u.i < 0);
-			return 4;
-		}
-	case 5:{		/* 6-byte signed integer */
-			/* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit
-			 * twos-complement integer.
-			 */
-			pMem->u.i =
-			    FOUR_BYTE_UINT(buf + 2) +
-			    (((i64) 1) << 32) * TWO_BYTE_INT(buf);
-			pMem->flags = MEM_Int;
-			testcase(pMem->u.i < 0);
-			return 6;
-		}
-	case 6:		/* 8-byte signed integer */
-	case 7:{		/* IEEE floating point */
-			/* These use local variables, so do them in a separate routine
-			 * to avoid having to move the frame pointer in the common case
-			 */
-			return serialGet(buf, serial_type, pMem);
-		}
-	case 8:		/* Integer 0 */
-	case 9:{		/* Integer 1 */
-			/* EVIDENCE-OF: R-12976-22893 Value is the integer 0. */
-			/* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */
-			pMem->u.i = serial_type - 8;
-			pMem->flags = MEM_Int;
-			return 0;
-		}
-	default:{
-			/* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in
-			 * length.
-			 * EVIDENCE-OF: R-28401-00140 Value is a string in the text encoding and
-			 * (N-13)/2 bytes in length.
-			 */
-			static const u16 aFlag[] =
-			    { MEM_Blob | MEM_Ephem, MEM_Str | MEM_Ephem };
-			pMem->z = (char *)buf;
-			pMem->n = (serial_type - 12) / 2;
-			pMem->flags = aFlag[serial_type & 1];
-			return pMem->n;
-		}
-	}
-	return 0;
-}
-
 /*
  * This routine is used to allocate sufficient space for an UnpackedRecord
  * structure large enough to be used with sqlVdbeRecordUnpack() if
-- 
2.25.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-02-02  7:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-28 11:49 [Tarantool-patches] [PATCH v1 1/1] sql: remove unused serialization functions Mergen Imeev via Tarantool-patches
2021-02-01 15:40 ` Nikita Pettik via Tarantool-patches
2021-02-02  7:57 ` Kirill Yukhin via Tarantool-patches
  -- strict thread matches above, loose matches on Subject: below --
2021-01-22 13:21 Mergen Imeev via Tarantool-patches
2021-01-27 22:28 ` Vladislav Shpilevoy via Tarantool-patches

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox