[Tarantool-patches] [PATCH v1 20/21] sql: remove MEM_Term flag
imeevma at tarantool.org
imeevma at tarantool.org
Fri Oct 8 20:32:09 MSK 2021
This patch removes the MEM_Term flag, because after changes in the SQL
built-in functions, this flag is no longer used.
Needed for #4145
---
src/box/sql/mem.c | 78 +++--------------------------------------
src/box/sql/mem.h | 36 -------------------
src/box/sql/printf.c | 18 ++++++++--
src/box/sql/vdbe.h | 4 ++-
src/box/sql/vdbeaux.c | 31 ++++------------
src/box/sql/whereexpr.c | 19 ++++++----
6 files changed, 41 insertions(+), 145 deletions(-)
diff --git a/src/box/sql/mem.c b/src/box/sql/mem.c
index a001ac8c5..7951f9ad5 100644
--- a/src/box/sql/mem.c
+++ b/src/box/sql/mem.c
@@ -346,21 +346,18 @@ void
mem_set_str0_ephemeral(struct Mem *mem, char *value)
{
set_str_const(mem, value, strlen(value), MEM_Ephem);
- mem->flags |= MEM_Term;
}
void
mem_set_str0_static(struct Mem *mem, char *value)
{
set_str_const(mem, value, strlen(value), MEM_Static);
- mem->flags |= MEM_Term;
}
void
mem_set_str0_allocated(struct Mem *mem, char *value)
{
set_str_dynamic(mem, value, strlen(value), 0);
- mem->flags |= MEM_Term;
}
int
@@ -392,7 +389,6 @@ mem_copy_str0(struct Mem *mem, const char *value)
if (mem_copy_str(mem, value, len + 1) != 0)
return -1;
mem->n = len;
- mem->flags |= MEM_Term;
return 0;
}
@@ -657,24 +653,12 @@ int_to_str0(struct Mem *mem)
return mem_copy_str0(mem, str);
}
-static inline int
-str_to_str0(struct Mem *mem)
-{
- assert(mem->type == MEM_TYPE_STR);
- if (sqlVdbeMemGrow(mem, mem->n + 1, 1) != 0)
- return -1;
- mem->z[mem->n] = '\0';
- mem->flags |= MEM_Term;
- mem->flags &= ~MEM_Scalar;
- return 0;
-}
-
static inline int
str_to_bin(struct Mem *mem)
{
assert(mem->type == MEM_TYPE_STR);
mem->type = MEM_TYPE_BIN;
- mem->flags &= ~(MEM_Term | MEM_Scalar);
+ mem->flags &= ~MEM_Scalar;
return 0;
}
@@ -725,18 +709,6 @@ bin_to_str(struct Mem *mem)
return 0;
}
-static inline int
-bin_to_str0(struct Mem *mem)
-{
- assert(mem->type == MEM_TYPE_BIN);
- if (sqlVdbeMemGrow(mem, mem->n + 1, 1) != 0)
- return -1;
- mem->z[mem->n] = '\0';
- mem->type = MEM_TYPE_STR;
- mem->flags = MEM_Term;
- return 0;
-}
-
static inline int
bin_to_uuid(struct Mem *mem)
{
@@ -1002,7 +974,7 @@ double_to_str0(struct Mem *mem)
sql_snprintf(BUF_SIZE, mem->z, "%!.15g", mem->u.r);
mem->n = strlen(mem->z);
mem->type = MEM_TYPE_STR;
- mem->flags = MEM_Term;
+ mem->flags = 0;
return 0;
}
@@ -1282,39 +1254,6 @@ mem_to_number(struct Mem *mem)
return -1;
}
-int
-mem_to_str0(struct Mem *mem)
-{
- assert(mem->type < MEM_TYPE_INVALID);
- switch (mem->type) {
- case MEM_TYPE_STR:
- if ((mem->flags & MEM_Term) != 0) {
- mem->flags &= ~MEM_Scalar;
- return 0;
- }
- return str_to_str0(mem);
- case MEM_TYPE_INT:
- case MEM_TYPE_UINT:
- return int_to_str0(mem);
- case MEM_TYPE_DOUBLE:
- return double_to_str0(mem);
- case MEM_TYPE_BOOL:
- return bool_to_str0(mem);
- case MEM_TYPE_BIN:
- return bin_to_str0(mem);
- case MEM_TYPE_MAP:
- return map_to_str0(mem);
- case MEM_TYPE_ARRAY:
- return array_to_str0(mem);
- case MEM_TYPE_UUID:
- return uuid_to_str0(mem);
- case MEM_TYPE_DEC:
- return dec_to_str0(mem);
- default:
- return -1;
- }
-}
-
int
mem_to_str(struct Mem *mem)
{
@@ -1761,15 +1700,6 @@ mem_get_bool(const struct Mem *mem, bool *b)
return -1;
}
-int
-mem_get_str0(const struct Mem *mem, const char **s)
-{
- if (mem->type != MEM_TYPE_STR || (mem->flags & MEM_Term) == 0)
- return -1;
- *s = mem->z;
- return 0;
-}
-
int
mem_get_bin(const struct Mem *mem, const char **s)
{
@@ -1812,7 +1742,7 @@ mem_copy(struct Mem *to, const struct Mem *from)
to->szMalloc = sqlDbMallocSize(to->db, to->zMalloc);
memcpy(to->zMalloc, to->z, to->n);
to->z = to->zMalloc;
- to->flags &= MEM_Term;
+ to->flags = 0;
return 0;
}
@@ -1829,7 +1759,7 @@ mem_copy_as_ephemeral(struct Mem *to, const struct Mem *from)
return;
if ((to->flags & (MEM_Static | MEM_Ephem)) != 0)
return;
- to->flags &= MEM_Term;
+ to->flags = 0;
to->flags |= MEM_Ephem;
return;
}
diff --git a/src/box/sql/mem.h b/src/box/sql/mem.h
index 76769835d..e29807035 100644
--- a/src/box/sql/mem.h
+++ b/src/box/sql/mem.h
@@ -98,13 +98,6 @@ struct Mem {
/** MEM is of SCALAR meta-type. */
#define MEM_Scalar 0x0002
#define MEM_Cleared 0x0200 /* NULL set by OP_Null, not from data */
-
-/* Whenever Mem contains a valid string or blob representation, one of
- * the following flags must be set to determine the memory management
- * policy for Mem.z. The MEM_Term flag tells us whether or not the
- * string is \000 or \u0000 terminated
- */
-#define MEM_Term 0x0400 /* String rep is nul terminated */
#define MEM_Static 0x1000 /* Mem.z points to a static string */
#define MEM_Ephem 0x2000 /* Mem.z points to an ephemeral string */
@@ -603,14 +596,6 @@ mem_to_number(struct Mem *mem);
int
mem_to_str(struct Mem *mem);
-/**
- * Convert the given MEM to STRING. This function and the function above define
- * the rules that are used to convert values of all other types to STRING. In
- * this function, the string received after convertion is NULL-terminated.
- */
-int
-mem_to_str0(struct Mem *mem);
-
/** Convert the given MEM to given type according to explicit cast rules. */
int
mem_cast_explicit(struct Mem *mem, enum field_type type);
@@ -715,27 +700,6 @@ mem_get_bool_unsafe(const struct Mem *mem)
return b;
}
-/**
- * Return value for MEM of STRING type if MEM contains a NULL-terminated string.
- * Otherwise convert value of the MEM to NULL-terminated string if possible and
- * return converted value. Original MEM is not changed.
- */
-int
-mem_get_str0(const struct Mem *mem, const char **s);
-
-/**
- * Return value for MEM of STRING type if MEM contains NULL-terminated string.
- * Otherwise convert MEM to MEM of string type that contains NULL-terminated
- * string and return its value. Return NULL if conversion is impossible.
- */
-static inline const char *
-mem_as_str0(struct Mem *mem)
-{
- if (mem_to_str0(mem) != 0)
- return NULL;
- return mem->z;
-}
-
/**
* Return value for MEM of VARBINARY type. For MEM of all other types convert
* value of the MEM to VARBINARY if possible and return converted value.
diff --git a/src/box/sql/printf.c b/src/box/sql/printf.c
index b4ab0d0f9..f261a731c 100644
--- a/src/box/sql/printf.c
+++ b/src/box/sql/printf.c
@@ -160,8 +160,22 @@ getTextArg(PrintfArguments * p)
{
if (p->nArg <= p->nUsed)
return 0;
- struct Mem *mem = p->apArg[p->nUsed++];
- return (char *)mem_as_str0(mem);
+ struct Mem mem;
+ mem_create(&mem);
+ mem_copy(&mem, p->apArg[p->nUsed++]);
+ if (mem_to_str(&mem) != 0) {
+ mem_destroy(&mem);
+ return NULL;
+ }
+ char *str = region_alloc(&fiber()->gc, mem.n + 1);
+ if (str == NULL) {
+ diag_set(OutOfMemory, mem.n + 1, "region", "str");
+ return NULL;
+ }
+ memcpy(str, mem.z, mem.n);
+ str[mem.n] = '\0';
+ mem_destroy(&mem);
+ return str;
}
/*
diff --git a/src/box/sql/vdbe.h b/src/box/sql/vdbe.h
index e40a1a0b3..89c83c43a 100644
--- a/src/box/sql/vdbe.h
+++ b/src/box/sql/vdbe.h
@@ -256,12 +256,14 @@ vdbe_metadata_set_col_autoincrement(struct Vdbe *p, int idx);
int
vdbe_metadata_set_col_span(struct Vdbe *p, int idx, const char *span);
+const struct Mem *
+vdbe_get_bound_value(struct Vdbe *vdbe, int id);
+
void sqlVdbeCountChanges(Vdbe *);
sql *sqlVdbeDb(Vdbe *);
void sqlVdbeSetSql(Vdbe *, const char *z, int n);
void sqlVdbeSwap(Vdbe *, Vdbe *);
VdbeOp *sqlVdbeTakeOpArray(Vdbe *, int *, int *);
-sql_value *sqlVdbeGetBoundValue(Vdbe *, int);
char *sqlVdbeExpandSql(Vdbe *, const char *);
/**
diff --git a/src/box/sql/vdbeaux.c b/src/box/sql/vdbeaux.c
index 3015760e1..a9ad7f50f 100644
--- a/src/box/sql/vdbeaux.c
+++ b/src/box/sql/vdbeaux.c
@@ -2290,31 +2290,12 @@ sqlVdbeDb(Vdbe * v)
return v->db;
}
-/*
- * Return a pointer to an sql_value structure containing the value bound
- * parameter iVar of VM v. Except, if the value is an SQL NULL, return
- * 0 instead. Unless it is NULL, apply type to the value before returning it.
- *
- * The returned value must be freed by the caller using sqlValueFree().
- */
-sql_value *
-sqlVdbeGetBoundValue(struct Vdbe *v, int iVar)
-{
- assert(iVar > 0);
- if (v) {
- Mem *pMem = &v->aVar[iVar - 1];
- if (!mem_is_null(pMem)) {
- sql_value *pRet = sqlValueNew(v->db);
- if (pRet == NULL)
- return NULL;
- if (mem_copy(pRet, pMem) != 0) {
- sqlValueFree(pRet);
- return NULL;
- }
- return pRet;
- }
- }
- return 0;
+const struct Mem *
+vdbe_get_bound_value(struct Vdbe *vdbe, int id)
+{
+ if (vdbe == NULL || id < 0 || id >= vdbe->nVar)
+ return NULL;
+ return &vdbe->aVar[id];
}
void
diff --git a/src/box/sql/whereexpr.c b/src/box/sql/whereexpr.c
index 6849f13ec..ad064d500 100644
--- a/src/box/sql/whereexpr.c
+++ b/src/box/sql/whereexpr.c
@@ -268,7 +268,7 @@ like_optimization_is_valid(Parse *pParse, Expr *pExpr, Expr **ppPrefix,
int cnt;
/* Database connection. */
sql *db = pParse->db;
- sql_value *pVal = 0;
+ const struct Mem *var = NULL;
/* Opcode of pRight. */
int op;
/* Result code to return. */
@@ -307,12 +307,18 @@ like_optimization_is_valid(Parse *pParse, Expr *pExpr, Expr **ppPrefix,
op = pRight->op;
if (op == TK_VARIABLE) {
- Vdbe *pReprepare = pParse->pReprepare;
- int iCol = pRight->iColumn;
- pVal = sqlVdbeGetBoundValue(pReprepare, iCol);
- if (pVal != NULL && mem_is_str(pVal)) {
- if (mem_as_str0(pVal) == NULL)
+ var = vdbe_get_bound_value(pParse->pReprepare,
+ pRight->iColumn - 1);
+ if (var != NULL && mem_is_str(var)) {
+ uint32_t size = var->n + 1;
+ char *str = region_alloc(&fiber()->gc, size);
+ if (str == NULL) {
+ diag_set(OutOfMemory, size, "region", "str");
return -1;
+ }
+ memcpy(str, var->z, var->n);
+ str[var->n] = '\0';
+ z = str;
}
assert(pRight->op == TK_VARIABLE || pRight->op == TK_REGISTER);
} else if (op == TK_STRING) {
@@ -357,7 +363,6 @@ like_optimization_is_valid(Parse *pParse, Expr *pExpr, Expr **ppPrefix,
}
rc = (z != 0);
- sqlValueFree(pVal);
return rc;
}
--
2.25.1
More information about the Tarantool-patches
mailing list