aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/postgres.sml
diff options
context:
space:
mode:
authorGravatar Adam Chlipala <adam@chlipala.net>2011-03-10 18:51:15 -0500
committerGravatar Adam Chlipala <adam@chlipala.net>2011-03-10 18:51:15 -0500
commitf7b3e616c3d16a85e0cc1de32e37e036c964294a (patch)
treeb141688cd684a68c9ca22d806b09af122a99bd51 /src/postgres.sml
parent7119e3b05218f975fe8b3f9a4c5fd4a680e05933 (diff)
Represent 'unit' as C 'int'; change pattern match compilation to avoid 'goto'; change Postgres prepared statement compilation to make life easier for the GCC escape analysis; all this in support of better tail call optimization
Diffstat (limited to 'src/postgres.sml')
-rw-r--r--src/postgres.sml84
1 files changed, 47 insertions, 37 deletions
diff --git a/src/postgres.sml b/src/postgres.sml
index 70360163..f713c753 100644
--- a/src/postgres.sml
+++ b/src/postgres.sml
@@ -669,29 +669,56 @@ fun p_ensql t e =
p_ensql t (box [string "(*", e, string ")"]),
string ")"]
-fun queryPrepared {loc, id, query, inputs, cols, doCols, nested = _} =
- box [string "PGconn *conn = uw_get_db(ctx);",
- newline,
- string "const int paramFormats[] = { ",
+fun makeParams inputs =
+ box [string "static const int paramFormats[] = { ",
p_list_sep (box [string ",", space])
(fn t => if isBlob t then string "1" else string "0") inputs,
string " };",
newline,
- string "const int paramLengths[] = { ",
- p_list_sepi (box [string ",", space])
- (fn i => fn Blob => string ("arg" ^ Int.toString (i + 1) ^ ".size")
- | Nullable Blob => string ("arg" ^ Int.toString (i + 1)
- ^ "?arg" ^ Int.toString (i + 1) ^ "->size:0")
- | _ => string "0") inputs,
- string " };",
- newline,
- string "const char *paramValues[] = { ",
- p_list_sepi (box [string ",", space])
- (fn i => fn t => p_ensql t (box [string "arg",
- string (Int.toString (i + 1))]))
+ if List.exists isBlob inputs then
+ box [string "const int *paramLengths = uw_malloc(ctx, ",
+ string (Int.toString (length inputs)),
+ string " * sizeof(int));",
+ newline,
+ p_list_sepi (box [])
+ (fn i => fn t =>
+ box [string "paramLengths[",
+ string (Int.toString i),
+ string "] = ",
+ case t of
+ Blob => string ("arg" ^ Int.toString (i + 1) ^ ".size")
+ | Nullable Blob => string ("arg" ^ Int.toString (i + 1)
+ ^ "?arg" ^ Int.toString (i + 1) ^ "->size:0")
+ | _ => string "0",
+ string ";",
+ newline]) inputs,
+ string " };",
+ newline]
+ else
+ box [string "const int *paramLengths = paramFormats;",
+ newline],
+
+ string "const char **paramValues = uw_malloc(ctx, ",
+ string (Int.toString (length inputs)),
+ string " * sizeof(char*));",
+ newline,
+ p_list_sepi (box [])
+ (fn i => fn t => box [string "paramValues[",
+ string (Int.toString i),
+ string "] = ",
+ p_ensql t (box [string "arg",
+ string (Int.toString (i + 1))]),
+ string ";",
+ newline])
inputs,
- string " };",
+ newline]
+
+fun queryPrepared {loc, id, query, inputs, cols, doCols, nested = _} =
+ box [string "PGconn *conn = uw_get_db(ctx);",
newline,
+
+ makeParams inputs,
+
newline,
string "PGresult *res = ",
if #persistent (Settings.currentProtocol ()) then
@@ -831,26 +858,9 @@ fun dml (loc, mode) =
fun dmlPrepared {loc, id, dml, inputs, mode} =
box [string "PGconn *conn = uw_get_db(ctx);",
newline,
- string "const int paramFormats[] = { ",
- p_list_sep (box [string ",", space])
- (fn t => if isBlob t then string "1" else string "0") inputs,
- string " };",
- newline,
- string "const int paramLengths[] = { ",
- p_list_sepi (box [string ",", space])
- (fn i => fn Blob => string ("arg" ^ Int.toString (i + 1) ^ ".size")
- | Nullable Blob => string ("arg" ^ Int.toString (i + 1)
- ^ "?arg" ^ Int.toString (i + 1) ^ "->size:0")
- | _ => string "0") inputs,
- string " };",
- newline,
- string "const char *paramValues[] = { ",
- p_list_sepi (box [string ",", space])
- (fn i => fn t => p_ensql t (box [string "arg",
- string (Int.toString (i + 1))]))
- inputs,
- string " };",
- newline,
+
+ makeParams inputs,
+
newline,
string "PGresult *res;",
newline,