diff --git a/README.md b/README.md index 0439f98..e8df1a6 100644 --- a/README.md +++ b/README.md @@ -58,8 +58,8 @@ SQL = "SELECT title FROM posts WHERE lang = $1 ORDER BY date DESC OFFSET 10 ROWS QueryDSL = [select('posts.title','author.name'), from(posts), join(author), on('author.author_id' = 'posts.author_id')] SQL = "SELECT posts.title,author.name FROM posts INNER JOIN author ON author.author_id = posts.author_id" -QueryDSL = [select(title), from(posts), where((lang = "es";lang='NULL')), order_by(desc(date), asc(title))] -SQL = "SELECT title FROM posts WHERE (lang = $1) OR (lang = NULL) ORDER BY date DESC,title ASC" +QueryDSL = [select(title), from(posts), where((lang = "es";is_null(lang))), order_by(desc(date), asc(title))] +SQL = "SELECT title FROM posts WHERE (lang = $1) OR (lang IS NULL) ORDER BY date DESC,title ASC" QueryDSL = [insert_into(test_table, [name]), values("test")] SQL = "INSERT INTO test_table (name) VALUES ($1)" diff --git a/messages.pl b/messages.pl index 5ee47e9..1606f3d 100644 --- a/messages.pl +++ b/messages.pl @@ -101,7 +101,7 @@ length(Params, NumberParams), int16(NumberParams, Bytes4), bind_message_params_bytes(Params, [], Bytes5), - append([Bytes1, Bytes2, Bytes3, Bytes4, Bytes5], PreBytes), + append([Bytes1, Bytes2, Bytes3, Bytes4, Bytes5, Bytes3], PreBytes), length(PreBytes, L), RealLength is L + 4, int32(RealLength, Bytes0), @@ -109,9 +109,7 @@ bind_message_params_bytes([], B, B). bind_message_params_bytes([null|Params], Bytes0, Bytes) :- - int32(-1, B1), - int16(0, B2), - append([B1, B2], B), + int32(-1, B), append(Bytes0, B, Bytes1), bind_message_params_bytes(Params, Bytes1, Bytes). @@ -119,8 +117,7 @@ chars_utf8bytes(Param, B2), length(B2, L), int32(L, B1), - int16(0, B3), - append([B1, B2, B3], B), + append([B1, B2], B), append(Bytes0, B, Bytes1), bind_message_params_bytes(Params, Bytes1, Bytes). diff --git a/sql_query.pl b/sql_query.pl index afb49f3..143a492 100644 --- a/sql_query.pl +++ b/sql_query.pl @@ -143,6 +143,15 @@ sql_cond(B, Vars1, Vars), ")". +sql_cond((\+ A), Vars0, Vars) --> + "NOT (", + sql_cond(A, Vars0, Vars), + ")". + +sql_cond(is_null(A), Vars0, Vars) --> + { sql_var(A, VarA, Vars0, Vars) }, + format_("~w IS NULL", [VarA]). + sql_cond(A = B, Vars0, Vars) --> { sql_var(A, VarA, Vars0, Vars1) }, { sql_var(B, VarB, Vars1, Vars) }, diff --git a/tests.lgt b/tests.lgt index 09b1499..6dd0803 100644 --- a/tests.lgt +++ b/tests.lgt @@ -105,8 +105,8 @@ test(sql_query_or) :- sql_query:sql_query( - [select(title), from(posts), where((lang = "es";lang='NULL')), order_by(desc(date), asc(title))], - "SELECT title FROM posts WHERE (lang = $1) OR (lang = NULL) ORDER BY date DESC,title ASC", + [select(title), from(posts), where((lang = "es";is_null(lang))), order_by(desc(date), asc(title))], + "SELECT title FROM posts WHERE (lang = $1) OR (lang IS NULL) ORDER BY date DESC,title ASC", [1-"es"] ). @@ -156,7 +156,19 @@ postgresql:sql(Connection, [select(id, name), from(test_table), where(name = "test")], Rows2), Rows2 = data([]). - + test(sql_query_2) :- + postgresql:connect("postgres", "postgres", '127.0.0.1', 5432, "postgres", Connection), + postgresql:query(Connection, "DROP TABLE IF EXISTS famous", ok), + postgresql:query(Connection, "DROP TABLE IF EXISTS country", ok), + postgresql:query(Connection, "CREATE TABLE country (iso_code varchar(2) PRIMARY KEY, name text)", ok), + postgresql:query(Connection, "CREATE TABLE famous (id serial PRIMARY KEY, name text, country varchar(2) REFERENCES country(iso_code), year int)", ok), + postgresql:sql(Connection, [insert_into(country, [iso_code, name]), values("ES", "España")], data([])), + postgresql:sql(Connection, [insert_into(country, [iso_code, name]), values("PT", "Portugal")], data([])), + postgresql:sql(Connection, [insert_into(famous, [name, country, year]), values("Miguel de Cervantes", "ES", 1547)], data([])), + postgresql:sql(Connection, [insert_into(famous, [name, country, year]), values("Magallanes", "PT", 1480)], data([])), + postgresql:sql(Connection, [insert_into(famous, [name, country, year]), values("Picasso", "ES", 1881)], data([])), + postgresql:sql(Connection, [select('famous.name','country.name'),from(famous),join(country),on('famous.country' = 'country.iso_code'),where((year > 1500,year < 2000)),order_by(asc(year))], Result), + Result = data([["Miguel de Cervantes", "España"], ["Picasso", "España"]]). :- end_object. \ No newline at end of file