Open mingodad opened 1 year ago
Testing the online playground I'm copying and pasting from the documentation and found this example https://cgsql.dev/cql-guide/ch10/#using-regions with an error:
--- <unnamed>
+++ <unnamed>
@@ -16,7 +16,7 @@
details text
);
-create proc get_detail(integer id_)
+create proc get_detail(id_ integer)
begin
select T1.id, T1.details, T2.name from details T1
inner join main T2 on T1.id = T2.id
@@ -32,7 +32,7 @@
f1_info text
);
-create proc get_detail(integer id_)
+create proc get_detail(id_ integer)
begin
select T1.id, T1.details, T2.name, f1_info from details T1
inner join f T2 on T1.id = T2.id
This is super cool :D
With this changes to check a 32bits build on a multilib Linux (because wasm is 32bits and I'm getting a nasty bug) :
------------------------ sources/common/Makefile_common ------------------------
index a9dcf6ff3..447da662a 100644
@@ -23,8 +23,8 @@ endif
SQLITE_LINK+=-pthread -ldl
CFLAGS+=-I$(CQL_DIR)
CFLAGS+=-I$O
-CFLAGS+=-g
-CFLAGS+=-Werror
+CFLAGS+=-g -m32
+CFLAGS+=-Wall #-Werror
ifdef CGSQL_GCC
CFLAGS += -std=c99
There is this warnings:
...
In file included from cql.h:38,
from ast.h:12,
from cg_common.h:10,
from sem.c:26:
sem.c: In function ‘sem_validate_object_ast_in_current_region’:
sem.c:1710:23: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
1710 | Contract(err_target && msg || !err_target && !msg);
| ~~~~~~~~~~~^~~~~~
sem.c:1710:3: note: in expansion of macro ‘Contract’
1710 | Contract(err_target && msg || !err_target && !msg);
| ^~~~~~~~
sem.c:1710:23: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
1710 | Contract(err_target && msg || !err_target && !msg);
| ~~~~~~~~~~~^~~~~~
sem.c:1710:3: note: in expansion of macro ‘Contract’
1710 | Contract(err_target && msg || !err_target && !msg);
| ^~~~~~~~
sem.c: In function ‘find_usable_table_or_view_even_deleted’:
sem.c:1763:23: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
1763 | Contract(err_target && msg || !err_target && !msg);
| ~~~~~~~~~~~^~~~~~
sem.c:1763:3: note: in expansion of macro ‘Contract’
1763 | Contract(err_target && msg || !err_target && !msg);
| ^~~~~~~~
sem.c:1763:23: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
1763 | Contract(err_target && msg || !err_target && !msg);
| ~~~~~~~~~~~^~~~~~
sem.c:1763:3: note: in expansion of macro ‘Contract’
1763 | Contract(err_target && msg || !err_target && !msg);
| ^~~~~~~~
sem.c: In function ‘find_usable_and_not_deleted_table_or_view’:
sem.c:1784:23: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
1784 | Contract(err_target && msg || !err_target && !msg);
| ~~~~~~~~~~~^~~~~~
sem.c:1784:3: note: in expansion of macro ‘Contract’
1784 | Contract(err_target && msg || !err_target && !msg);
| ^~~~~~~~
sem.c:1784:23: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
1784 | Contract(err_target && msg || !err_target && !msg);
| ~~~~~~~~~~~^~~~~~
sem.c:1784:3: note: in expansion of macro ‘Contract’
1784 | Contract(err_target && msg || !err_target && !msg);
| ^~~~~~~~
sem.c: In function ‘sem_select_expr_list_con’:
sem.c:10925:25: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
10925 | Invariant(from_jptr && query_parts || !from_jptr && !query_parts);
| ~~~~~~~~~~^~~~~~~~~~~~~~
sem.c:10925:5: note: in expansion of macro ‘Invariant’
10925 | Invariant(from_jptr && query_parts || !from_jptr && !query_parts);
| ^~~~~~~~~
sem.c:10925:25: warning: suggest parentheses around ‘&&’ within ‘||’ [-Wparentheses]
10925 | Invariant(from_jptr && query_parts || !from_jptr && !query_parts);
| ~~~~~~~~~~^~~~~~~~~~~~~~
sem.c:10925:5: note: in expansion of macro ‘Invariant’
10925 | Invariant(from_jptr && query_parts || !from_jptr && !query_parts);
| ^~~~~~~~~
sem.c: In function ‘sem_validate_one_interface’:
sem.c:19190:44: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
19190 | symtab_add(names, proc_sptr->names[i], (void *)(uint64_t)i);
| ^
sem.c:19206:28: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
19206 | uint32_t j = (uint32_t)(uint64_t)entry->val;
| ^
In file included from cql.h:38,
from ast.h:12,
from cg_common.h:10,
from sem.c:26:
sem.c: In function ‘sem_declare_cursor_for_expr’:
sem.c:20923:12: warning: the address of ‘is_ast_declare_cursor’ will always evaluate as ‘true’ [-Waddress]
20923 | Contract(is_ast_declare_cursor);
| ^~~~~~~~~~~~~~~~~~~~~
sem.c:20923:3: note: in expansion of macro ‘Contract’
20923 | Contract(is_ast_declare_cursor);
| ^~~~~~~~
sem.c: At top level:
sem.c:22696:1: warning: multi-line comment [-Wcomment]
22696 | // #define LOGGING_PROC_BEGIN \
| ^
sem.c:22702:1: warning: multi-line comment [-Wcomment]
22702 | // #define LOGGING_PROC_END \
| ^
...
cg_c.c: In function ‘cg_result_set_type_decl’:
cg_c.c:442:34: warning: value computed is not used [-Wunused-value]
442 | rt->result_set_type_decl_extra && rt->result_set_type_decl_extra(output, sym, ref);
| ^~
cg_c.c: In function ‘cg_intern_piece’:
cg_c.c:4406:21: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
4406 | return (int32_t)(int64_t)(entry->val);
| ^
cg_c.c: In function ‘cg_proc_result_set’:
cg_c.c:7941:26: warning: value computed is not used [-Wunused-value]
7941 | rt->register_proc_name && rt->register_proc_name(name);
| ^~
...
cg_schema.c: In function ‘topological_walk_recreate_group_deps_helper’:
cg_schema.c:1521:59: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
1521 | int32_t neighbor_ordinal = neighbor_entry ? (int32_t) (int64_t) (neighbor_entry->val) : -1;
| ^
cg_schema.c:1527:16: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1527 | entry->val = (void*) (int64_t) (max_group_ordinal++);
| ^
cg_schema.c: In function ‘topological_walk_recreate_group_deps’:
cg_schema.c:1547:34: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
1547 | int32_t ordinal = (int32_t)(int64_t)(entry.val);
| ^
cg_schema.c:1567:50: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1567 | symtab_add(recreate_group_ordinals, gname, (void*)(int64_t)max_group_ordinal++);
| ^
cg_schema.c:1570:48: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
1570 | (*recreates)[i].group_ordinal = (int32_t)(int64_t)entry->val;
| ^
...
cg_stats.c: In function ‘cg_stats_create_proc_stmt’:
cg_stats.c:71:69: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
71 | bprintf(stats_output, "\"%s\",\"%s\",%lld\n", name, entry->sym, (llint_t)entry->val);
| ^
...
cg_lua.c: In function ‘cg_lua_proc_result_set’:
cg_lua.c:4988:26: warning: value computed is not used [-Wunused-value]
4988 | rt->register_proc_name && rt->register_proc_name(name);
| ^~
cc -DSQLITE_DEBUG -I./ -Iout -g -m32 -Wall -o out/cql out/cql.y.o out/cql.o out/ast.o out/gen_sql.o out/sem.o out/list.o out/bytebuf.o out/charbuf.o out/cg_common.o out/cg_c.o out/cg_java.o out/cg_objc.o out/symtab.o out/compat.o out/cg_schema.o out/crc64xz.o out/sha256.o out/cg_json_schema.o out/cg_test_helpers.o out/encoders.o out/unit_tests.o out/cg_query_plan.o out/minipool.o out/cg_udf.o out/rt.o out/eval.o out/rewrite.o out/printf.o out/flow.o out/cg_stats.o out/cg_lua.o
...
In file included from cqlrt.c:400:
cqlrt_common.c:1254:53: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
1254 | *prc = sqlite3_bind_int64(*pstmt, column, (int64_t)obj_ref);
| ^
...
In file included from cqlrt.c:400:
cqlrt_common.c:1318:53: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
1318 | *prc = sqlite3_bind_int64(*pstmt, column, (int64_t)nullable_obj_ref);
| ^
In file included from cqlrt.c:400:
cqlrt_common.c: In function ‘cql_key_retain_str’:
cqlrt_common.c:2676:16: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
2676 | cql_retain((cql_type_ref)(key));
| ^
cqlrt_common.c: In function ‘cql_key_release_str’:
cqlrt_common.c:2682:17: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
2682 | cql_release((cql_type_ref)(key));
| ^
cqlrt_common.c: In function ‘cql_key_str_hash’:
cqlrt_common.c:2687:26: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
2687 | return cql_string_hash((cql_string_ref)key);
| ^
cqlrt_common.c: In function ‘cql_key_str_eq’:
cqlrt_common.c:2691:27: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
2691 | return cql_string_equal((cql_string_ref)key1, (cql_string_ref)key2);
| ^
cqlrt_common.c:2691:49: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
2691 | return cql_string_equal((cql_string_ref)key1, (cql_string_ref)key2);
| ^
cqlrt_common.c: In function ‘cql_facet_add’:
cqlrt_common.c:2721:36: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
2721 | result = cql_hashtab_add(self, (cql_int64)name, crc);
| ^
cqlrt_common.c: In function ‘cql_facet_find’:
cqlrt_common.c:2731:57: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
2731 | cql_hashtab_entry *payload = cql_hashtab_find(self, (cql_int64)name);
| ^
cqlrt_common.c: In function ‘cql_facet_upsert’:
cqlrt_common.c:2745:57: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
2745 | cql_hashtab_entry *payload = cql_hashtab_find(self, (cql_int64)name);
| ^
cqlrt_common.c:2748:38: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
2748 | result = cql_hashtab_add(self, (cql_int64)name, crc);
| ^
...
In file included from cqlrt.c:400:
cqlrt_common.c: In function ‘cql_partition_key_release’:
cqlrt_common.c:3442:14: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
3442 | void *pv = (void *)key;
| ^
cqlrt_common.c: In function ‘cql_partition_val_release’:
cqlrt_common.c:3457:26: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
3457 | cql_object_ref obj = (cql_object_ref)(val & ~(cql_int64)1);
| ^
cqlrt_common.c:3463:26: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
3463 | cql_bytebuf * buffer = (cql_bytebuf *)val;
| ^
cqlrt_common.c: In function ‘cql_key_cursor_hash’:
cqlrt_common.c:3512:29: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
3512 | self->c_key.cursor_data = (void *)key;
| ^
cqlrt_common.c: In function ‘cql_key_cursor_eq’:
cqlrt_common.c:3524:29: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
3524 | self->c_key.cursor_data = (void *)key1;
| ^
cqlrt_common.c:3525:30: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
3525 | self->c_key2.cursor_data = (void *)key2;
| ^
cqlrt_common.c: In function ‘cql_partition_cursor’:
cqlrt_common.c:3606:57: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
3606 | cql_hashtab_entry *entry = cql_hashtab_find(self->ht, (cql_int64)key->cursor_data);
| ^
cqlrt_common.c:3611:11: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
3611 | buf = (cql_bytebuf *)entry->val;
| ^
cqlrt_common.c:3622:48: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
3622 | cql_bool added = cql_hashtab_add(self->ht, (cql_int64)k, (cql_int64)buf);
| ^
cqlrt_common.c:3622:62: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
3622 | cql_bool added = cql_hashtab_add(self->ht, (cql_int64)k, (cql_int64)buf);
| ^
cqlrt_common.c: In function ‘cql_extract_partition’:
cqlrt_common.c:3655:59: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
3655 | cql_hashtab_entry *entry = cql_hashtab_find(self->ht, (cql_int64)key->cursor_data);
| ^
cqlrt_common.c:3664:37: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
3664 | cql_object_ref result_set = (cql_object_ref)(entry->val & ~(cql_int64)1);
| ^
cqlrt_common.c:3670:13: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
3670 | buf = (cql_bytebuf *)entry->val;
| ^
cqlrt_common.c:3701:22: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
3701 | entry->val = 1|(cql_int64)result; // store the result but set the LSB so we know it's not a buffer
| ^
...
In file included from cqlrt.c:400:
cqlrt_common.c: In function ‘cql_string_dictionary_add’:
cqlrt_common.c:3807:53: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
3807 | cql_hashtab_entry *entry = cql_hashtab_find(self, (cql_int64)key);
| ^
In file included from cqlrt.c:8:
cqlrt_common.c:3811:24: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
3811 | cql_string_release((cql_string_ref)entry->val);
| ^
cqlrt.h:108:62: note: in definition of macro ‘cql_string_release’
108 | #define cql_string_release(string) cql_release((cql_type_ref)string);
| ^~~~~~
In file included from cqlrt.c:400:
cqlrt_common.c:3812:18: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
3812 | entry->val = (cql_int64)val;
| ^
cqlrt_common.c:3817:32: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
3817 | return cql_hashtab_add(self, (cql_int64)key, (cql_int64)val);
| ^
cqlrt_common.c:3817:48: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
3817 | return cql_hashtab_add(self, (cql_int64)key, (cql_int64)val);
| ^
cqlrt_common.c: In function ‘cql_string_dictionary_find’:
cqlrt_common.c:3833:53: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
3833 | cql_hashtab_entry *entry = cql_hashtab_find(self, (cql_int64)key);
| ^
cqlrt_common.c:3835:18: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
3835 | return entry ? (cql_string_ref)entry->val : NULL;
| ^
...
Building again for 64bits and doing the following tests with valgrind:
valgrind sources/out/cql --in schema.cql --rt schema --cg schema.sql0
==22885== Memcheck, a memory error detector
==22885== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==22885== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
==22885== Command: sources/out/cql --in schema.cql --rt schema --cg schema.sql0
==22885==
==22885== Conditional jump or move depends on uninitialised value(s)
==22885== at 0x155A3C: sem_try_resolve_column (sem.c:5883)
==22885== by 0x15693A: sem_resolve_id_with_type (sem.c:6230)
==22885== by 0x156A44: sem_resolve_id (sem.c:6252)
==22885== by 0x1571D7: sem_resolve_id_expr (sem.c:6423)
==22885== by 0x18D03A: sem_expr_str (sem.c:23620)
==22885== by 0x1631A8: sem_expr (sem.c:10061)
==22885== by 0x163126: sem_root_expr (sem.c:10047)
==22885== by 0x146854: sem_validate_index_expr_for_jptr (sem.c:693)
==22885== by 0x1798EB: sem_name_check (sem.c:16951)
==22885== by 0x14D2F0: sem_validate_name_list (sem.c:3191)
==22885== by 0x14E10D: sem_create_index_stmt (sem.c:3416)
==22885== by 0x18C796: sem_one_stmt (sem.c:23322)
==22885==
==22885==
==22885== HEAP SUMMARY:
==22885== in use at exit: 17,074 bytes in 4 blocks
==22885== total heap usage: 166 allocs, 162 frees, 190,405 bytes allocated
==22885==
==22885== LEAK SUMMARY:
==22885== definitely lost: 0 bytes in 0 blocks
==22885== indirectly lost: 0 bytes in 0 blocks
==22885== possibly lost: 0 bytes in 0 blocks
==22885== still reachable: 17,074 bytes in 4 blocks
==22885== suppressed: 0 bytes in 0 blocks
==22885== Rerun with --leak-check=full to see details of leaked memory
==22885==
==22885== Use --track-origins=yes to see where uninitialised values come from
==22885== For lists of detected and suppressed errors, rerun with: -s
==22885== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Here is schema.cql
:
@attribute(an_attribute=(1,('foo', 'bar')))
CREATE TABLE foo(
id INTEGER,
name TEXT
);
create index foo_name on foo(name);
And here is the output schema.sql0
:
-- @generated SignedSource<<deadbeef8badf00ddefec8edfacefeed>>
@ATTRIBUTE(an_attribute=(1, ('foo', 'bar')))
CREATE TABLE foo(
id INTEGER,
name TEXT
);
CREATE INDEX foo_name ON foo (name);
This change seems to fix this problem:
-------------------------------- sources/sem.c --------------------------------
index 2a4429339..fa3ea2d09 100644
@@ -2538,6 +2538,7 @@ static sem_struct * new_sem_struct(CSTR name, uint32_t count) {
sptr->names = _ast_pool_new_array(CSTR, count);
sptr->kinds = _ast_pool_new_array(CSTR, count);
sptr->semtypes = _ast_pool_new_array(sem_t, count);
+ sptr->is_backed = false;
for (int32_t i = 0; i < count; i++) {
sptr->names[i] = NULL;
Also when building for 32bits and adding -Wall -Wextra
show several comparison unsigned/signed in for loops that seems not difficult to fix.
Pretty sure I've never built the compiler for 32 bits.
Get Outlook for Androidhttps://aka.ms/AAb9ysg
From: Domingo Alvarez Duarte @.> Sent: Saturday, December 17, 2022 2:43:11 AM To: facebookincubator/CG-SQL @.> Cc: Rico Mariani @.>; Comment @.> Subject: Re: [facebookincubator/CG-SQL] CG-SQL-Lua online playground (Issue #164)
Also when building for 32bits and adding -Wall -Wextra show several comparison unsigned/signed in for loops that seems not difficult to fix.
— Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Ffacebookincubator%2FCG-SQL%2Fissues%2F164%23issuecomment-1356168798&data=05%7C01%7C%7C1f122c2d519545fc09eb08dae01b7f03%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C638068705959851568%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=qmv36rCdmw%2FlBU86ilQ02%2FIiuCZKu0iI4QGkDPTJ34Q%3D&reserved=0, or unsubscribehttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAHC3V7272F2OXE6Z57VGGYDWNWKL7ANCNFSM6AAAAAAS6PMXVM&data=05%7C01%7C%7C1f122c2d519545fc09eb08dae01b7f03%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C638068705959851568%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=VPIoz2aUxCO4tTXynOsdm2xt11%2BoDrT2Qo28FBBjdF8%3D&reserved=0. You are receiving this because you commented.Message ID: @.***>
Also I just updated the online playground to also show C
code and noticed that the @echo
directive do not take in consideration if the selected runtime matches the one specified on the @echo
line:
@echo lua, "function printf(...) io.write(cql_printf(...)) end\n";
@echo lua, "go(sqlite3.open_memory())\n";
Selecting the C
runtime outputs:
function printf(...) io.write(cql_printf(...)) end
go(sqlite3.open_memory())
Obs.: My bad it does take in account the selected runtime.
I've added more samples from sources/lua_demo
and found a bug probably in emscripten
the demo t6
fail in wasm due to a different number conversion:
Output from native (clang15):
print("testing code gen for min long and max long")
min_l0 = (-9223372036854775807 - 1) --!!!<<< notice here
min_l1 = 0x8000000000000000
min_l2 = 1 << 63
min_l3 = (-9223372036854775807 - 1)
max_l0 = 9223372036854775807
max_l1 = 0x7fffffffffffffff
max_l2 = ~ (1 << 63)
max_l3 = 9223372036854775807
Output from wasm (clang15):
print("testing code gen for min long and max long")
min_l0 = - 9223372036854775808 --!!!<<< notice here
min_l1 = 0x8000000000000000
min_l2 = 1 << 63
min_l3 = (-9223372036854775807 - 1)
max_l0 = 9223372036854775807
max_l1 = 0x7fffffffffffffff
max_l2 = ~ (1 << 63)
max_l3 = 9223372036854775807
It seems to be something with muslc
I just build cql
on an alpine64
vm:
Linux alpine.xxx 5.15.71-0-lts ...
gcc version 11.2.1 20220219 (Alpine 11.2.1...)
And here is the diff for the execution of cql --in t6.sql --rt lua --cg t6.lua
:
--- /home/mingo/dev/dadbiz++/third-party/dad/CG-SQL0/sources/lua_demo/t6.lua
+++ /home/mingo/dev/dadbiz++/third-party/dad/CG-SQL0/sources/lua_demo/t6-alpine.lua
@@ -29,7 +29,7 @@
CREATE PROC go ()
BEGIN
CALL print("testing code gen for min long and max long");
- LET min_l0 := -9223372036854775808L;
+ LET min_l0 := -9223372036854775808;
LET min_l1 := 0x8000000000000000L;
LET min_l2 := 1L << 63;
LET min_l3 := -9223372036854775808L;
@@ -47,8 +47,8 @@
CALL expect(min_l1 + max_l0 = -1);
CALL expect(min_l2 + max_l0 = -1);
CALL expect(min_l3 + max_l0 = -1);
- CALL expect(-9223372036854775808L + 9223372036854775807L = -1);
- CALL expect(9223372036854775807L + -9223372036854775808L = -1);
+ CALL expect(-9223372036854775808 + 9223372036854775807L = -1);
+ CALL expect(9223372036854775807L + -9223372036854775808 = -1);
CALL expect(0x7fffffffffffffffL + 0x8000000000000000L = -1);
CALL expect(0x8000000000000000L + 0x7fffffffffffffffL = -1);
DECLARE z REAL NOT NULL;
@@ -73,7 +73,7 @@
local z = 0.0
print("testing code gen for min long and max long")
- min_l0 = (-9223372036854775807 - 1)
+ min_l0 = - 9223372036854775808
min_l1 = 0x8000000000000000
min_l2 = 1 << 63
min_l3 = (-9223372036854775807 - 1)
@@ -91,8 +91,8 @@
expect(min_l1 + max_l0 == - 1)
expect(min_l2 + max_l0 == - 1)
expect(min_l3 + max_l0 == - 1)
- expect((-9223372036854775807 - 1) + 9223372036854775807 == - 1)
- expect(9223372036854775807 + (-9223372036854775807 - 1) == - 1)
+ expect(- 9223372036854775808 + 9223372036854775807 == - 1)
+ expect(9223372036854775807 + - 9223372036854775808 == - 1)
expect(0x7fffffffffffffff + 0x8000000000000000 == - 1)
expect(0x8000000000000000 + 0x7fffffffffffffff == - 1)
z = cql_to_float(9223372036854775807)
I did a change on cql.l
to see what's happening:
{d}+ { char *s = Strdup(yytext); yylval.sval = s; printf("%s : %lld : %d : %d\n", s, atoll(s), 0x7fffffff, atoll(s) <= 0x7fffffff); return atoll(s) <= 0x7fffffff ? INTLIT: LONGLIT; }
Executing cql --in t6.sql --rt lua --cg t6.lua
.
And here is the output on alpine linux
(muslc):
9223372036854775808 : -9223372036854775808 : 2147483647 : 1
63 : 63 : 2147483647 : 1
63 : 63 : 2147483647 : 1
9223372036854775807 : 9223372036854775807 : 2147483647 : 0
63 : 63 : 2147483647 : 1
63 : 63 : 2147483647 : 1
1 : 1 : 2147483647 : 1
1 : 1 : 2147483647 : 1
1 : 1 : 2147483647 : 1
1 : 1 : 2147483647 : 1
9223372036854775808 : -9223372036854775808 : 2147483647 : 1
9223372036854775807 : 9223372036854775807 : 2147483647 : 0
1 : 1 : 2147483647 : 1
9223372036854775807 : 9223372036854775807 : 2147483647 : 0
9223372036854775808 : -9223372036854775808 : 2147483647 : 1
1 : 1 : 2147483647 : 1
1 : 1 : 2147483647 : 1
1 : 1 : 2147483647 : 1
9223372036854775807 : 9223372036854775807 : 2147483647 : 0
1 : 1 : 2147483647 : 1
1 : 1 : 2147483647 : 1
And here the output on Ubuntu 18.04:
9223372036854775808 : 9223372036854775807 : 2147483647 : 0
63 : 63 : 2147483647 : 1
63 : 63 : 2147483647 : 1
9223372036854775807 : 9223372036854775807 : 2147483647 : 0
63 : 63 : 2147483647 : 1
63 : 63 : 2147483647 : 1
1 : 1 : 2147483647 : 1
1 : 1 : 2147483647 : 1
1 : 1 : 2147483647 : 1
1 : 1 : 2147483647 : 1
9223372036854775808 : 9223372036854775807 : 2147483647 : 0
9223372036854775807 : 9223372036854775807 : 2147483647 : 0
1 : 1 : 2147483647 : 1
9223372036854775807 : 9223372036854775807 : 2147483647 : 0
9223372036854775808 : 9223372036854775807 : 2147483647 : 0
1 : 1 : 2147483647 : 1
1 : 1 : 2147483647 : 1
1 : 1 : 2147483647 : 1
9223372036854775807 : 9223372036854775807 : 2147483647 : 0
1 : 1 : 2147483647 : 1
1 : 1 : 2147483647 : 1
It seems that the problem is with atoll
on musl
testing with this program:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
const char *s = "9223372036854775808";
long long ll = atoll(s);
long long ll2 = strtoll (s, (char **) NULL, 10);
int imax = 0x7fffffff;
printf("%s : %lld : %lld : %d : %d\n", s, ll, ll2, imax, ll <= imax);
return 0;
}
This is the output on alpine linux
(musl):
9223372036854775808 : -9223372036854775808 : 9223372036854775807 : 2147483647 : 1
And here is on Ubuntu 18.04:
9223372036854775808 : 9223372036854775807 : 9223372036854775807 : 2147483647 : 0
The output of atoll
and strtoll
do not match on musl
that is used on alpine linux
and also on wasm/emscripten
.
For the playground I just replaced atoll
with strtoll
till the bug get fixed and it's running the t6.sql
sample fine.
Also while making tests on alpine linux
I needed to replace all #!/bin/bash
by #!/bin/sh
to be able to build, it doesn't seem that this project is using any bashism
so using #!/bin/sh
would give less headaches on other operating systems.
After reporting the problem to musl
mailing list the conclusion seem that musl
decided to try signal an out of range error giving a different value than the one from strtoll
because in theory atoll
do not set errno
on error.
See this sample that shows it:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int main(int argc, char *argv[])
{
const char *s = "9223372036854775808";
printf("before atoll errno = %d : %s\n", errno, strerror(errno));
long long ll = atoll(s);
printf("after atoll errno = %d : %s\n", errno, strerror(errno));
errno = 0;
long long ll2 = strtoll (s, (char **) NULL, 10);
printf("after strtoll errno = %d : %s\n", errno, strerror(errno));
int imax = 0x7fffffff;
printf("%s : %lld : %lld : %d : %d\n", s, ll, ll2, imax, ll <= imax);
return 0;
}
Output from glibc
:
./test-ll
before atoll errno = 0 : Success
after atoll errno = 34 : Numerical result out of range
after strtoll errno = 34 : Numerical result out of range
9223372036854775808 : 9223372036854775807 : 9223372036854775807 : 2147483647 : 0
Output from musl
:
before atoll errno = 0 : No error information
after atoll errno = 0 : No error information
after strtoll errno = 34 : Result not representable
9223372036854775808 : -9223372036854775808 : 9223372036854775807 : 2147483647 : 1
So the code on cql.l
need to take in account errno
when trying to convert numbers and definitely do not use atoll
.
Here is the mailing list discussion https://www.openwall.com/lists/musl/2022/12/18/1
I've just created the first draft of an online playground for
CG-SQL
withLua
runtime at https://mingodad.github.io/CG-SQL-Lua-playground/ .The repository is at https://github.com/mingodad/CG-SQL-Lua-playground .
Any feedback is welcome !