[tarantool-patches] Re: [PATCH v3 05/10] sql: refactor sql_expr_compile to return AST

Kirill Shcherbatov kshcherbatov at tarantool.org
Fri Jun 15 19:21:44 MSK 2018


> 1. Here parser.region leaks.
> 2. If a TARANTOOL_ERROR has occurred and parsed_expr had been set before it,
> then you return not NULL, but should return NULL.
> 
> And you should destroy the expression. Looks like it was a leak before your
> patch. Lets always delete all the parsed expressions in parser_destroy (here
> only parsed_expr is). And in this function on success nullify this member
> before destroy.

diff --git a/src/box/sql/prepare.c b/src/box/sql/prepare.c
index e43fbcb..34ee8e3 100644
--- a/src/box/sql/prepare.c
+++ b/src/box/sql/prepare.c
@@ -454,5 +454,6 @@ sql_parser_destroy(Parse *parser)
        }
        parser->disableLookaside = 0;
        sqlite3DbFree(db, parser->zErrMsg);
+       sql_expr_delete(db, parser->parsed_expr, false);
        region_destroy(&parser->region);
 }
diff --git a/src/box/sql/tokenize.c b/src/box/sql/tokenize.c
index d6f5a43..9e4576b 100644
--- a/src/box/sql/tokenize.c
+++ b/src/box/sql/tokenize.c
@@ -559,16 +559,20 @@ sql_expr_compile(sqlite3 *db, const char *expr, int expr_len)
        char *stmt = (char *)region_alloc(&parser.region, len + 1);
        if (stmt == NULL) {
                diag_set(OutOfMemory, len + 1, "region_alloc", "stmt");
-               return NULL;
+               goto end;
        }
        sprintf(stmt, "%s%.*s", outer, expr_len, expr);
 
        char *sql_error;
-       if (sqlite3RunParser(&parser, stmt, &sql_error) != SQLITE_OK &&
-           parser.rc != SQL_TARANTOOL_ERROR)
-               diag_set(ClientError, ER_SQL, sql_error);
-       else
+       if (sqlite3RunParser(&parser, stmt, &sql_error) != SQLITE_OK) {
+               if (parser.rc != SQL_TARANTOOL_ERROR)
+                       diag_set(ClientError, ER_SQL, sql_error);
+       } else {
                expression = parser.parsed_expr;
+               parser.parsed_expr = NULL;
+       }
+
+end:
        sql_parser_destroy(&parser);
        return expression;
 }





More information about the Tarantool-patches mailing list