Skip to content
Snippets Groups Projects
Commit 6e759a50 authored by Dmitry Simonenko's avatar Dmitry Simonenko
Browse files

tntsql-u64: sql parser support for 64bit numbers added

parent 460aa77c
No related branches found
No related tags found
No related merge requests found
......@@ -32,7 +32,8 @@ enum {
TNT_TK_ERROR = -1,
TNT_TK_EOF = 0,
TNT_TK_NONE = 1000,
TNT_TK_NUM,
TNT_TK_NUM32,
TNT_TK_NUM64,
TNT_TK_ID,
TNT_TK_KEY,
TNT_TK_TABLE,
......@@ -61,7 +62,8 @@ enum {
struct tnt_tk {
int tk;
union {
int32_t i;
int32_t i32;
int64_t i64;
struct tnt_utf8 s;
} v;
int line, col;
......@@ -72,7 +74,8 @@ struct tnt_tk {
/* token object accessors */
#define TNT_TK_S(TK) (&(TK)->v.s)
#define TNT_TK_I(TK) ((TK)->v.i)
#define TNT_TK_I32(TK) ((TK)->v.i32)
#define TNT_TK_I64(TK) ((TK)->v.i64)
/* lexer object */
......
......@@ -31,6 +31,7 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <connector/c/include/tarantool/tnt.h>
......@@ -161,7 +162,8 @@ tnt_lex_nameof(int tk)
switch (tk) {
case TNT_TK_EOF: return "End-Of-Statement";
case TNT_TK_ERROR: return "ERROR";
case TNT_TK_NUM: return "NUM";
case TNT_TK_NUM32: return "NUM32";
case TNT_TK_NUM64: return "NUM64";
case TNT_TK_STRING: return "STRING";
case TNT_TK_ID: return "ID";
case TNT_TK_KEY: return "KEY";
......@@ -202,7 +204,7 @@ tnt_lex(struct tnt_lex *l, struct tnt_tk **tk)
if (l->count) {
*tk = tnt_lex_pop(l);
if ((*tk)->tk == TNT_TK_PUNCT)
return TNT_TK_I(*tk);
return TNT_TK_I32(*tk);
return (*tk)->tk;
}
......@@ -276,16 +278,16 @@ tnt_lex(struct tnt_lex *l, struct tnt_tk **tk)
}
}
*tk = tnt_lex_tk(l, TNT_TK_PUNCT, line, col);
TNT_TK_I(*tk) = ch;
TNT_TK_I32(*tk) = ch;
return ch;
}
numeric: /* numeric value */
if (isdigit(ch)) {
int32_t num = 0;
int64_t num = 0;
while (1) {
if (isdigit(tnt_lex_chr(l)))
num *= 10, num += tnt_lex_chr(l) - '0';
num = (num * 10) + tnt_lex_chr(l) - '0';
else
break;
ssize_t r = tnt_lex_next(l);
......@@ -296,9 +298,19 @@ tnt_lex(struct tnt_lex *l, struct tnt_tk **tk)
}
if (minus)
num *= -1;
*tk = tnt_lex_tk(l, TNT_TK_NUM, line, col);
TNT_TK_I(*tk) = num;
return TNT_TK_NUM;
if (tnt_lex_chr(l) == 'L') {
ssize_t r = tnt_lex_next(l);
if (r == -1)
return tnt_lex_error(l, "utf8 decoding error");
} else
if (num >= INT_MIN && num < INT_MAX) {
*tk = tnt_lex_tk(l, TNT_TK_NUM32, line, col);
TNT_TK_I32(*tk) = (int32_t)num;
return TNT_TK_NUM32;
}
*tk = tnt_lex_tk(l, TNT_TK_NUM64, line, col);
TNT_TK_I64(*tk) = num;
return TNT_TK_NUM64;
}
/* skipping to the end of lexem */
......@@ -324,7 +336,8 @@ tnt_lex(struct tnt_lex *l, struct tnt_tk **tk)
for (i = 0 ; tnt_keywords[i].name ; i++) {
if (tnt_keywords[i].size != size)
continue;
if (strncasecmp(tnt_keywords[i].name, (const char*)TNT_UTF8_CHAR(&l->buf, start), size) == 0) {
if (strncasecmp(tnt_keywords[i].name,
(const char*)TNT_UTF8_CHAR(&l->buf, start), size) == 0) {
*tk = tnt_lex_tk(l, tnt_keywords[i].tk, line, col);
return tnt_keywords[i].tk;
}
......@@ -343,7 +356,7 @@ tnt_lex(struct tnt_lex *l, struct tnt_tk **tk)
goto id;
}
*tk = tnt_lex_tk(l, idtk, line, col);
TNT_TK_I(*tk) = id;
TNT_TK_I32(*tk) = id;
return idtk;
}
......
......@@ -126,13 +126,20 @@ tnt_sql_keyval(struct tnt_sql *sql, struct tnt_tuple *tu, bool key, struct tnt_t
struct tnt_tk *v = NULL;
if (tnt_lex(sql->l, &v) == TNT_TK_ERROR)
return tnt_sql_error(sql, NULL, "%s", sql->l->error);
if (v->tk != TNT_TK_NUM && v->tk != TNT_TK_STRING)
return tnt_sql_error(sql, k, "expected NUM or STRING");
/* tuple field operation */
if (v->tk == TNT_TK_NUM)
tnt_tuple_add(tu, (char*)&TNT_TK_I(v), 4);
else
tnt_tuple_add(tu, (char*)TNT_TK_S(v)->data, TNT_TK_S(v)->size);
switch (v->tk) {
case TNT_TK_NUM32:
tnt_tuple_add(tu, (char*)&TNT_TK_I32(v), 4);
break;
case TNT_TK_NUM64:
tnt_tuple_add(tu, (char*)&TNT_TK_I64(v), 8);
break;
case TNT_TK_STRING:
tnt_tuple_add(tu, (char*)TNT_TK_S(v)->data,
TNT_TK_S(v)->size);
break;
default:
return tnt_sql_error(sql, k, "expected NUM32 or NUM64 or STRING");
}
return true;
}
......@@ -149,9 +156,9 @@ tnt_sql_kv_select(struct tnt_sql *sql, struct tnt_tuple *tu, int32_t *index)
if (rc == false)
return false;
if (*index == -1)
*index = TNT_TK_I(key);
*index = TNT_TK_I32(key);
else
if (*index != TNT_TK_I(key))
if (*index != TNT_TK_I32(key))
return tnt_sql_error(sql, key,
"select key values must refer to the same index");
return true;
......@@ -178,7 +185,7 @@ tnt_sql_stmt_update(struct tnt_sql *sql, struct tnt_tuple *tu, struct tnt_stream
switch (tnt_lex(sql->l, &v)) {
/* k = k op v */
case TNT_TK_KEY:
if (TNT_TK_I(k) != TNT_TK_I(v)) {
if (TNT_TK_I32(k) != TNT_TK_I32(v)) {
tnt_sql_error(sql, k, "can't update on different keys");
goto error;
}
......@@ -199,35 +206,39 @@ tnt_sql_stmt_update(struct tnt_sql *sql, struct tnt_tuple *tu, struct tnt_stream
tnt_sql_error(sql, k, "bad update operation");
goto error;
}
tnt_expect(tnt_sqltkv(sql, TNT_TK_NUM, &v));
tnt_update_arith(u, TNT_TK_I(k), ut, TNT_TK_I(v));
tnt_expect(tnt_sqltkv(sql, TNT_TK_NUM32, &v));
tnt_update_arith(u, TNT_TK_I32(k), ut, TNT_TK_I32(v));
break;
/* k = string */
case TNT_TK_STRING:
tnt_update_assign(u, TNT_TK_I(k), (char*)TNT_TK_S(v)->data,
tnt_update_assign(u, TNT_TK_I32(k), (char*)TNT_TK_S(v)->data,
TNT_TK_S(v)->size);
break;
/* k = num */
case TNT_TK_NUM:
tnt_update_assign(u, TNT_TK_I(k), (char*)&TNT_TK_I(v), 4);
/* k = num32 */
case TNT_TK_NUM32:
tnt_update_assign(u, TNT_TK_I32(k), (char*)&TNT_TK_I32(v), 4);
break;
/* k = num64 */
case TNT_TK_NUM64:
tnt_update_assign(u, TNT_TK_I64(k), (char*)&TNT_TK_I64(v), 8);
break;
/* k = splice(k, a, b) */
case TNT_TK_SPLICE: {
struct tnt_tk *field, *off, *len, *list;
tnt_expect(tnt_sqltk(sql, '('));
tnt_expect(tnt_sqltkv(sql, TNT_TK_KEY, &field));
if (TNT_TK_I(k) != TNT_TK_I(field)) {
if (TNT_TK_I32(k) != TNT_TK_I32(field)) {
tnt_sql_error(sql, k, "can't update on different keys");
goto error;
}
tnt_expect(tnt_sqltk(sql, ','));
tnt_expect(tnt_sqltkv(sql, TNT_TK_NUM, &off));
tnt_expect(tnt_sqltkv(sql, TNT_TK_NUM32, &off));
tnt_expect(tnt_sqltk(sql, ','));
tnt_expect(tnt_sqltkv(sql, TNT_TK_NUM, &len));
tnt_expect(tnt_sqltkv(sql, TNT_TK_NUM32, &len));
tnt_expect(tnt_sqltk(sql, ','));
tnt_expect(tnt_sqltkv(sql, TNT_TK_STRING, &list));
tnt_expect(tnt_sqltk(sql, ')'));
tnt_update_splice(u, TNT_TK_I(k), TNT_TK_I(off), TNT_TK_I(len),
tnt_update_splice(u, TNT_TK_I32(k), TNT_TK_I32(off), TNT_TK_I32(len),
(char*)TNT_TK_S(list)->data,
TNT_TK_S(list)->size);
break;
......@@ -246,7 +257,7 @@ tnt_sql_stmt_update(struct tnt_sql *sql, struct tnt_tuple *tu, struct tnt_stream
/* predicate */
tnt_expect(tnt_sql_kv(sql, tu, true));
tnt_expect(tnt_sqltk(sql, TNT_TK_EOF));
if (tnt_update(sql->s, TNT_TK_I(tn), 0, tu, u) == -1) {
if (tnt_update(sql->s, TNT_TK_I32(tn), 0, tu, u) == -1) {
tnt_sql_error(sql, tn, "update failed");
goto error;
}
......@@ -293,7 +304,7 @@ tnt_sql_stmt(struct tnt_sql *sql)
flags = TNT_FLAG_REPLACE;
tnt_expect(tnt_sqltk(sql, ')'));
tnt_expect(tnt_sqltk(sql, TNT_TK_EOF));
if (tnt_insert(sql->s, TNT_TK_I(tn), flags, &tu) == -1) {
if (tnt_insert(sql->s, TNT_TK_I32(tn), flags, &tu) == -1) {
tnt_sql_error(sql, tk, "insert failed");
goto error;
}
......@@ -311,7 +322,7 @@ tnt_sql_stmt(struct tnt_sql *sql)
/* predicate */
tnt_expect(tnt_sql_kv(sql, &tu, true));
tnt_expect(tnt_sqltk(sql, TNT_TK_EOF));
if (tnt_delete(sql->s, TNT_TK_I(tn), 0, &tu) == -1) {
if (tnt_delete(sql->s, TNT_TK_I32(tn), 0, &tu) == -1) {
tnt_sql_error(sql, tk, "delete failed");
goto error;
}
......@@ -342,13 +353,13 @@ tnt_sql_stmt(struct tnt_sql *sql)
uint32_t limit = UINT32_MAX;
if (tnt_sqltry(sql, TNT_TK_LIMIT)) {
struct tnt_tk *ltk;
tnt_expect(tnt_sqltkv(sql, TNT_TK_NUM, &ltk));
limit = TNT_TK_I(ltk);
tnt_expect(tnt_sqltkv(sql, TNT_TK_NUM32, &ltk));
limit = TNT_TK_I32(ltk);
} else
if (sql->error)
goto error;
tnt_expect(tnt_sqltk(sql, TNT_TK_EOF));
if (tnt_select(sql->s, TNT_TK_I(tn), index, 0, limit, &tuples) == -1) {
if (tnt_select(sql->s, TNT_TK_I32(tn), index, 0, limit, &tuples) == -1) {
tnt_sql_error(sql, tk, "select failed");
goto error;
}
......
......@@ -29,6 +29,7 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <connector/c/include/tarantool/tnt.h>
#include <connector/c/include/tarantool/tnt_net.h>
......@@ -792,13 +793,22 @@ static void tt_tnt_lex_ws(struct tt_test *test) {
/* lex integer */
static void tt_tnt_lex_int(struct tt_test *test) {
unsigned char sz[] = "\f\r\n 123 34\n\t\r56";
unsigned char sz[] = "\f\r\n 123 34\n\t\r56 888L56 2147483646 2147483647 "
"-2147483648 -2147483649 72057594037927935";
struct tnt_lex l;
tnt_lex_init(&l, sz, sizeof(sz) - 1);
struct tnt_tk *tk;
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM && TNT_TK_I(tk) == 123);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM && TNT_TK_I(tk) == 34);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM && TNT_TK_I(tk) == 56);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == 123);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == 34);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == 56);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM64 && TNT_TK_I64(tk) == 888);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == 56);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == INT_MAX - 1);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM64 && TNT_TK_I64(tk) == INT_MAX);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == INT_MIN);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM64 && TNT_TK_I64(tk) == INT_MIN - 1LL);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM64 && TNT_TK_I64(tk) == 72057594037927935LL);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_EOF);
tnt_lex_free(&l);
}
......@@ -809,14 +819,14 @@ static void tt_tnt_lex_punct(struct tt_test *test) {
struct tnt_lex l;
tnt_lex_init(&l, sz, sizeof(sz) - 1);
struct tnt_tk *tk;
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM && TNT_TK_I(tk) == 123);
TT_ASSERT(tnt_lex(&l, &tk) == ',' && TNT_TK_I(tk) == ',');
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM && TNT_TK_I(tk) == 34);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM && TNT_TK_I(tk) == -10);
TT_ASSERT(tnt_lex(&l, &tk) == ':' && TNT_TK_I(tk) == ':');
TT_ASSERT(tnt_lex(&l, &tk) == '('&& TNT_TK_I(tk) == '(');
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM && TNT_TK_I(tk) == 56);
TT_ASSERT(tnt_lex(&l, &tk) == ')' && TNT_TK_I(tk) == ')');
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == 123);
TT_ASSERT(tnt_lex(&l, &tk) == ',' && TNT_TK_I32(tk) == ',');
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == 34);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == -10);
TT_ASSERT(tnt_lex(&l, &tk) == ':' && TNT_TK_I32(tk) == ':');
TT_ASSERT(tnt_lex(&l, &tk) == '('&& TNT_TK_I32(tk) == '(');
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_NUM32 && TNT_TK_I32(tk) == 56);
TT_ASSERT(tnt_lex(&l, &tk) == ')' && TNT_TK_I32(tk) == ')');
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_EOF);
tnt_lex_free(&l);
}
......@@ -874,13 +884,13 @@ static void tt_tnt_lex_kt(struct tt_test *test) {
struct tnt_lex l;
tnt_lex_init(&l, sz, sizeof(sz) - 1);
struct tnt_tk *tk;
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_KEY && TNT_TK_I(tk) == 0);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_KEY && TNT_TK_I(tk) == 20);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_TABLE && TNT_TK_I(tk) == 0);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_KEY && TNT_TK_I(tk) == 1000);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_TABLE && TNT_TK_I(tk) == 55);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_KEY && TNT_TK_I(tk) == 1);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_TABLE && TNT_TK_I(tk) == 8);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_KEY && TNT_TK_I32(tk) == 0);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_KEY && TNT_TK_I32(tk) == 20);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_TABLE && TNT_TK_I32(tk) == 0);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_KEY && TNT_TK_I32(tk) == 1000);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_TABLE && TNT_TK_I32(tk) == 55);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_KEY && TNT_TK_I32(tk) == 1);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_TABLE && TNT_TK_I32(tk) == 8);
TT_ASSERT(tnt_lex(&l, &tk) == TNT_TK_EOF);
tnt_lex_free(&l);
}
......@@ -908,22 +918,22 @@ static void tt_tnt_lex_stack(struct tt_test *test) {
struct tnt_lex l;
tnt_lex_init(&l, sz, sizeof(sz) - 1);
struct tnt_tk *tk1, *tk2, *tk3, *tk4, *tk5, *tk6;
TT_ASSERT(tnt_lex(&l, &tk1) == TNT_TK_NUM);
TT_ASSERT(tnt_lex(&l, &tk1) == TNT_TK_NUM32);
TT_ASSERT(tnt_lex(&l, &tk2) == TNT_TK_STRING);
TT_ASSERT(tnt_lex(&l, &tk3) == ',');
TT_ASSERT(tnt_lex(&l, &tk4) == '.');
TT_ASSERT(tnt_lex(&l, &tk5) == TNT_TK_NUM);
TT_ASSERT(tnt_lex(&l, &tk5) == TNT_TK_NUM32);
TT_ASSERT(tnt_lex(&l, &tk6) == TNT_TK_EOF);
tnt_lex_push(&l, tk5);
tnt_lex_push(&l, tk4);
tnt_lex_push(&l, tk3);
tnt_lex_push(&l, tk2);
tnt_lex_push(&l, tk1);
TT_ASSERT(tnt_lex(&l, &tk1) == TNT_TK_NUM);
TT_ASSERT(tnt_lex(&l, &tk1) == TNT_TK_NUM32);
TT_ASSERT(tnt_lex(&l, &tk2) == TNT_TK_STRING);
TT_ASSERT(tnt_lex(&l, &tk3) == ',');
TT_ASSERT(tnt_lex(&l, &tk4) == '.');
TT_ASSERT(tnt_lex(&l, &tk5) == TNT_TK_NUM);
TT_ASSERT(tnt_lex(&l, &tk5) == TNT_TK_NUM32);
TT_ASSERT(tnt_lex(&l, &tk6) == TNT_TK_EOF);
tnt_lex_free(&l);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment