plsql: Fix readline/output async. Improve arg mode.
authorJoel Martin <github@martintribe.org>
Wed, 4 May 2016 03:29:07 +0000 (22:29 -0500)
committerJoel Martin <github@martintribe.org>
Sun, 22 May 2016 06:16:02 +0000 (00:16 -0600)
15 files changed:
.gitignore
Makefile
plsql/io.sql
plsql/step0_repl.sql
plsql/step1_read_print.sql
plsql/step2_eval.sql
plsql/step3_env.sql
plsql/step4_if_fn_do.sql
plsql/step5_tco.sql
plsql/step6_file.sql
plsql/step7_quote.sql
plsql/step8_macros.sql
plsql/step9_try.sql
plsql/stepA_mal.sql
plsql/wrap.sh

index f110f74..6f2d57e 100644 (file)
@@ -88,8 +88,6 @@ objpascal/pas-readline
 objpascal/regexpr/Source/RegExpr.ppu
 perl/mal.pl
 php/mal.php
-plsql/io.sql
-plsql/step*.sql
 ps/mal.ps
 python/mal.pyz
 r/mal.r
index b81f6a6..20e5aca 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -64,6 +64,7 @@ OPTIONAL=1
 mal_TEST_OPTS = --start-timeout 60 --test-timeout 120
 miniMAL_TEST_OPTS = --start-timeout 60 --test-timeout 120
 plpgsql_TEST_OPTS = --start-timeout 60 --test-timeout 180
+plsql_TEST_OPTS = --start-timeout 60 --test-timeout 120
 
 DOCKERIZE=
 
@@ -108,7 +109,8 @@ test_EXCLUDES += test^bash^step5   # never completes at 10,000
 test_EXCLUDES += test^make^step5   # no TCO capability (iteration or recursion)
 test_EXCLUDES += test^mal^step5    # host impl dependent
 test_EXCLUDES += test^matlab^step5 # never completes at 10,000
-test_EXCLUDES += test^plpgsql^step5    # too slow for 10,000
+test_EXCLUDES += test^plpgsql^step5 # too slow for 10,000
+test_EXCLUDES += test^plsql^step5  # too slow for 10,000
 
 perf_EXCLUDES = mal  # TODO: fix this
 
index da2c053..1ba4753 100644 (file)
@@ -54,6 +54,7 @@ show errors;
 CREATE OR REPLACE PACKAGE BODY io AS
 
 PROCEDURE open(sid integer) AS
+    PRAGMA AUTONOMOUS_TRANSACTION;
 BEGIN
     -- DBMS_OUTPUT.PUT_LINE('stream_open(' || sid || ') start');
     UPDATE stream SET data = '', rl_prompt = '', open = 1
@@ -63,6 +64,7 @@ BEGIN
 END;
 
 PROCEDURE close(sid integer) AS
+    PRAGMA AUTONOMOUS_TRANSACTION;
 BEGIN
     -- DBMS_OUTPUT.PUT_LINE('stream_close(' || sid || ') start');
     UPDATE stream SET rl_prompt = '', open = 0
@@ -89,7 +91,7 @@ BEGIN
         -- LOCK TABLE stream IN EXCLUSIVE MODE;
         SELECT data, open INTO input, isopen FROM stream
             WHERE stream_id = sid;
-        IF isopen = 1 AND input IS NOT NULL THEN
+        IF input IS NOT NULL THEN
             UPDATE stream SET data = '' WHERE stream_id = sid;
             COMMIT;
             RETURN trim(TRAILING chr(10) FROM input);
@@ -114,6 +116,11 @@ FUNCTION readline(prompt varchar, sid integer DEFAULT 0) RETURN CLOB IS
 BEGIN
     -- set prompt / request readline style input
     -- LOCK TABLE stream IN EXCLUSIVE MODE;
+    IF sid = 0 THEN
+        wait_flushed(1);
+    ELSIF sid = 1 THEN
+        wait_flushed(0);
+    END IF;
     UPDATE stream SET rl_prompt = prompt WHERE stream_id = sid;
     COMMIT;
 
@@ -152,7 +159,7 @@ BEGIN
         LOCK TABLE stream IN EXCLUSIVE MODE;
         SELECT open, rl_prompt INTO isopen, prompt
             FROM stream WHERE stream_id = sid;
-        SELECT count(*) INTO datas FROM stream WHERE data IS NOT NULL;
+        SELECT count(stream_id) INTO datas FROM stream WHERE data IS NOT NULL;
 
         IF isopen = 0 THEN
             raise_application_error(-20001,
@@ -184,8 +191,8 @@ BEGIN
     sleep := 0.05;
     WHILE true
     LOOP
-        SELECT count(*) INTO pending FROM stream
-            WHERE stream_id = sid AND data IS NOT NULL; 
+        SELECT count(stream_id) INTO pending FROM stream
+            WHERE stream_id = sid AND data IS NOT NULL;
         IF pending = 0 THEN RETURN; END IF;
         DBMS_LOCK.SLEEP(sleep);
         IF sleep < 0.5 THEN
index b48ee39..7da8032 100644 (file)
@@ -47,7 +47,8 @@ BEGIN
             END IF;
 
             EXCEPTION WHEN OTHERS THEN
-                IF SQLCODE = -20001 THEN  -- io streams closed
+                IF SQLCODE = -20001 THEN  -- io read stream closed
+                    io.close(1);  -- close output stream
                     RETURN 0;
                 END IF;
                 io.writeline('Error: ' || SQLERRM);
index 08107a7..4c5c6f4 100644 (file)
@@ -55,7 +55,9 @@ BEGIN
             END IF;
 
             EXCEPTION WHEN OTHERS THEN
-                IF SQLCODE = -20001 THEN  -- io streams closed
+                IF SQLCODE = -20001 THEN  -- io read stream closed
+                    stream_writeline('closing stream 1');
+                    io.close(1);  -- close output stream
                     RETURN 0;
                 END IF;
                 io.writeline('Error: ' || SQLERRM);
index 2373de3..a8e6aa8 100644 (file)
@@ -161,7 +161,8 @@ BEGIN
             END IF;
 
             EXCEPTION WHEN OTHERS THEN
-                IF SQLCODE = -20001 THEN  -- io streams closed
+                IF SQLCODE = -20001 THEN  -- io read stream closed
+                    io.close(1);  -- close output stream
                     RETURN 0;
                 END IF;
                 io.writeline('Error: ' || SQLERRM);
index 0f6d588..b715aa7 100644 (file)
@@ -198,7 +198,8 @@ BEGIN
             END IF;
 
             EXCEPTION WHEN OTHERS THEN
-                IF SQLCODE = -20001 THEN  -- io streams closed
+                IF SQLCODE = -20001 THEN  -- io read stream closed
+                    io.close(1);  -- close output stream
                     RETURN 0;
                 END IF;
                 io.writeline('Error: ' || SQLERRM);
index 73e921b..0609037 100644 (file)
@@ -186,7 +186,8 @@ BEGIN
             END IF;
 
             EXCEPTION WHEN OTHERS THEN
-                IF SQLCODE = -20001 THEN  -- io streams closed
+                IF SQLCODE = -20001 THEN  -- io read stream closed
+                    io.close(1);  -- close output stream
                     RETURN 0;
                 END IF;
                 io.writeline('Error: ' || SQLERRM);
index 7272a52..882d1cc 100644 (file)
@@ -193,7 +193,8 @@ BEGIN
             END IF;
 
             EXCEPTION WHEN OTHERS THEN
-                IF SQLCODE = -20001 THEN  -- io streams closed
+                IF SQLCODE = -20001 THEN  -- io read stream closed
+                    io.close(1);  -- close output stream
                     RETURN 0;
                 END IF;
                 io.writeline('Error: ' || SQLERRM);
index 997d327..1be14bc 100644 (file)
@@ -235,10 +235,18 @@ BEGIN
     line := REP('(def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) ")")))))');
 
     IF argv.COUNT() > 0 THEN
-        line := REP('(load-file "' ||
-                TREAT(M(argv(1)) AS mal_str_type).val_str ||
-                '")');
-        RETURN 0;
+        BEGIN
+            line := REP('(load-file "' ||
+                    TREAT(M(argv(1)) AS mal_str_type).val_str ||
+                    '")');
+            io.close(1);  -- close output stream
+            RETURN 0;
+        EXCEPTION WHEN OTHERS THEN
+            io.writeline('Error: ' || SQLERRM);
+            io.writeline(dbms_utility.format_error_backtrace);
+            io.close(1);  -- close output stream
+            RAISE;
+        END;
     END IF;
 
     WHILE true LOOP
@@ -250,7 +258,8 @@ BEGIN
             END IF;
 
             EXCEPTION WHEN OTHERS THEN
-                IF SQLCODE = -20001 THEN  -- io streams closed
+                IF SQLCODE = -20001 THEN  -- io read stream closed
+                    io.close(1);  -- close output stream
                     RETURN 0;
                 END IF;
                 io.writeline('Error: ' || SQLERRM);
index b813492..c9e7535 100644 (file)
@@ -270,10 +270,18 @@ BEGIN
     line := REP('(def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) ")")))))');
 
     IF argv.COUNT() > 0 THEN
-        line := REP('(load-file "' ||
-                TREAT(M(argv(1)) AS mal_str_type).val_str ||
-                '")');
-        RETURN 0;
+        BEGIN
+            line := REP('(load-file "' ||
+                    TREAT(M(argv(1)) AS mal_str_type).val_str ||
+                    '")');
+            io.close(1);  -- close output stream
+            RETURN 0;
+        EXCEPTION WHEN OTHERS THEN
+            io.writeline('Error: ' || SQLERRM);
+            io.writeline(dbms_utility.format_error_backtrace);
+            io.close(1);  -- close output stream
+            RAISE;
+        END;
     END IF;
 
     WHILE true LOOP
@@ -285,7 +293,8 @@ BEGIN
             END IF;
 
             EXCEPTION WHEN OTHERS THEN
-                IF SQLCODE = -20001 THEN  -- io streams closed
+                IF SQLCODE = -20001 THEN  -- io read stream closed
+                    io.close(1);  -- close output stream
                     RETURN 0;
                 END IF;
                 io.writeline('Error: ' || SQLERRM);
index 6240086..aed41d8 100644 (file)
@@ -329,10 +329,18 @@ BEGIN
     line := REP('(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))');
 
     IF argv.COUNT() > 0 THEN
-        line := REP('(load-file "' ||
-                TREAT(M(argv(1)) AS mal_str_type).val_str ||
-                '")');
-        RETURN 0;
+        BEGIN
+            line := REP('(load-file "' ||
+                    TREAT(M(argv(1)) AS mal_str_type).val_str ||
+                    '")');
+            io.close(1);  -- close output stream
+            RETURN 0;
+        EXCEPTION WHEN OTHERS THEN
+            io.writeline('Error: ' || SQLERRM);
+            io.writeline(dbms_utility.format_error_backtrace);
+            io.close(1);  -- close output stream
+            RAISE;
+        END;
     END IF;
 
     WHILE true LOOP
@@ -344,7 +352,8 @@ BEGIN
             END IF;
 
             EXCEPTION WHEN OTHERS THEN
-                IF SQLCODE = -20001 THEN  -- io streams closed
+                IF SQLCODE = -20001 THEN  -- io read stream closed
+                    io.close(1);  -- close output stream
                     RETURN 0;
                 END IF;
                 io.writeline('Error: ' || SQLERRM);
index 942bc38..90f0d37 100644 (file)
@@ -415,10 +415,18 @@ BEGIN
     line := REP('(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))');
 
     IF argv.COUNT() > 0 THEN
-        line := REP('(load-file "' ||
-                TREAT(M(argv(1)) AS mal_str_type).val_str ||
-                '")');
-        RETURN 0;
+        BEGIN
+            line := REP('(load-file "' ||
+                    TREAT(M(argv(1)) AS mal_str_type).val_str ||
+                    '")');
+            io.close(1);  -- close output stream
+            RETURN 0;
+        EXCEPTION WHEN OTHERS THEN
+            io.writeline('Error: ' || SQLERRM);
+            io.writeline(dbms_utility.format_error_backtrace);
+            io.close(1);  -- close output stream
+            RAISE;
+        END;
     END IF;
 
     WHILE true LOOP
@@ -430,7 +438,8 @@ BEGIN
             END IF;
 
             EXCEPTION WHEN OTHERS THEN
-                IF SQLCODE = -20001 THEN  -- io streams closed
+                IF SQLCODE = -20001 THEN  -- io read stream closed
+                    io.close(1);  -- close output stream
                     RETURN 0;
                 END IF;
                 io.writeline('Error: ' || SQLERRM);
index ff1b48b..e87041c 100644 (file)
@@ -418,23 +418,32 @@ BEGIN
     line := REP('(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) (let* (condvar (gensym)) `(let* (~condvar ~(first xs)) (if ~condvar ~condvar (or ~@(rest xs)))))))))');
 
     IF argv.COUNT() > 0 THEN
-        line := REP('(load-file "' ||
-                TREAT(M(argv(1)) AS mal_str_type).val_str ||
-                '")');
-        RETURN 0;
+        BEGIN
+            line := REP('(load-file "' ||
+                    TREAT(M(argv(1)) AS mal_str_type).val_str ||
+                    '")');
+            io.close(1);  -- close output stream
+            RETURN 0;
+        EXCEPTION WHEN OTHERS THEN
+            io.writeline('Error: ' || SQLERRM);
+            io.writeline(dbms_utility.format_error_backtrace);
+            io.close(1);  -- close output stream
+            RAISE;
+        END;
     END IF;
 
     line := REP('(println (str "Mal [" *host-language* "]"))');
     WHILE true LOOP
         BEGIN
             line := io.readline('user> ', 0);
-            IF line IS NULL OR line = EMPTY_CLOB() THEN CONTINUE; END IF;
+            IF line = EMPTY_CLOB() THEN CONTINUE; END IF;
             IF line IS NOT NULL THEN
                 io.writeline(REP(line));
             END IF;
 
             EXCEPTION WHEN OTHERS THEN
-                IF SQLCODE = -20001 THEN  -- io streams closed
+                IF SQLCODE = -20001 THEN  -- io read stream closed
+                    io.close(1);  -- close output stream
                     RETURN 0;
                 END IF;
                 io.writeline('Error: ' || SQLERRM);
index 686f479..a61f3bc 100755 (executable)
@@ -3,8 +3,6 @@
 RL_HISTORY_FILE=${HOME}/.mal-history
 SKIP_INIT="${SKIP_INIT:-}"
 
-#MALDIR=$(readlink -f $(dirname $0)/..)
-#echo MALDIR: ${MALDIR}
 SQLPLUS="sqlplus -S system/oracle"
 
 FILE_PID=
@@ -40,6 +38,7 @@ while true; do
     echo "${out}"
 done
 ) &
+STDOUT_PID=$!
 
 # Perform readline input into stream table when requested
 (
@@ -66,7 +65,7 @@ while true; do
       echo -en "\n/" ) \
         | ${SQLPLUS} >/dev/null || break
 done
-echo -e "BEGIN io.close(0); io.close(1); END;\n/" \
+echo -e "BEGIN io.close(0); END;\n/" \
     | ${SQLPLUS} > /dev/null
 ) <&0 >&1 &
 
@@ -105,8 +104,6 @@ FILE_PID=$!
 
 res=0
 shift
-#echo "CREATE OR REPLACE DIRECTORY ROOTDIR AS '${MALDIR}';" \
-#    | ${SQLPLUS} > /dev/null
 if [ $# -gt 0 ]; then
     # If there are command line arguments then run a command and exit
     args=$(for a in "$@"; do echo -n "\"$a\" "; done)
@@ -119,8 +116,6 @@ else
         | ${SQLPLUS} > /dev/null
     res=$?
 fi
-# TODO: fix this
-sleep 2
-echo -e "BEGIN io.close(0); io.close(1); END;\n/" \
-    | ${SQLPLUS} > /dev/null
+# Wait for output to flush
+wait ${STDOUT_PID}
 exit ${res}