diff --git hplsql/pom.xml hplsql/pom.xml
index fc1c527..73dd47f 100644
--- hplsql/pom.xml
+++ hplsql/pom.xml
@@ -79,6 +79,12 @@
${junit.version}
test
+
+ org.apache.hive
+ hive-jdbc
+ 1.2.1
+ test
+
diff --git hplsql/src/main/antlr4/org/apache/hive/hplsql/Hplsql.g4 hplsql/src/main/antlr4/org/apache/hive/hplsql/Hplsql.g4
index 852716b..70312b2 100644
--- hplsql/src/main/antlr4/org/apache/hive/hplsql/Hplsql.g4
+++ hplsql/src/main/antlr4/org/apache/hive/hplsql/Hplsql.g4
@@ -33,6 +33,8 @@ single_block_stmt : // Single BEGIN END blo
stmt :
assignment_stmt
+ | allocate_cursor_stmt
+ | associate_locator_stmt
| break_stmt
| call_stmt
| close_stmt
@@ -117,6 +119,14 @@ assignment_stmt_select_item :
(ident | (T_OPEN_P ident (T_COMMA ident)* T_CLOSE_P)) T_COLON? T_EQUAL T_OPEN_P select_stmt T_CLOSE_P
;
+allocate_cursor_stmt:
+ T_ALLOCATE ident T_CURSOR T_FOR ((T_RESULT T_SET) | T_PROCEDURE) ident
+ ;
+
+associate_locator_stmt :
+ T_ASSOCIATE (T_RESULT T_SET)? (T_LOCATOR | T_LOCATORS) T_OPEN_P ident (T_COMMA ident)* T_CLOSE_P T_WITH T_PROCEDURE ident
+ ;
+
break_stmt :
T_BREAK
;
@@ -151,12 +161,15 @@ declare_condition_item : // Condition declaration
;
declare_cursor_item : // Cursor declaration
- (T_CURSOR ident | ident T_CURSOR) declare_cursor_return? (T_IS | T_AS | T_FOR) (select_stmt | expr )
+ (T_CURSOR ident | ident T_CURSOR) (cursor_with_return | cursor_without_return)? (T_IS | T_AS | T_FOR) (select_stmt | expr )
+ ;
+
+cursor_with_return :
+ T_WITH T_RETURN T_ONLY? (T_TO (T_CALLER | T_CLIENT))?
;
-declare_cursor_return :
+cursor_without_return :
T_WITHOUT T_RETURN
- | T_WITH T_RETURN T_ONLY? (T_TO (T_CALLER | T_CLIENT))?
;
declare_handler_item : // Condition handler declaration
@@ -238,6 +251,7 @@ dtype : // Data types
| T_INT
| T_INTEGER
| T_NUMBER
+ | T_RESULT_SET_LOCATOR T_VARYING
| T_SMALLINT
| T_STRING
| T_TIMESTAMP
@@ -261,7 +275,7 @@ dtype_default : // Default clause in variable declaration
;
create_function_stmt :
- (T_ALTER | T_CREATE (T_OR T_REPLACE)? | T_REPLACE) T_FUNCTION ident create_routine_params create_function_return (T_AS | T_IS)? single_block_stmt
+ (T_ALTER | T_CREATE (T_OR T_REPLACE)? | T_REPLACE) T_FUNCTION ident create_routine_params? create_function_return (T_AS | T_IS)? single_block_stmt
;
create_function_return :
@@ -269,7 +283,7 @@ create_function_return :
;
create_procedure_stmt :
- (T_ALTER | T_CREATE (T_OR T_REPLACE)? | T_REPLACE) (T_PROCEDURE | T_PROC) ident create_routine_params create_routine_options? (T_AS | T_IS)? label? single_block_stmt (ident T_SEMICOLON)?
+ (T_ALTER | T_CREATE (T_OR T_REPLACE)? | T_REPLACE) (T_PROCEDURE | T_PROC) ident create_routine_params? create_routine_options? (T_AS | T_IS)? label? single_block_stmt (ident T_SEMICOLON)?
;
create_routine_params :
@@ -287,7 +301,7 @@ create_routine_options :
create_routine_option :
T_LANGUAGE T_SQL
| T_SQL T_SECURITY (T_CREATOR | T_DEFINER | T_INVOKER | T_OWNER)
- | T_DYNAMIC T_RESULT T_SETS L_INT
+ | T_DYNAMIC? T_RESULT T_SETS L_INT
;
drop_stmt : // DROP statement
@@ -886,10 +900,12 @@ null_const : // NULL constant
non_reserved_words : // Tokens that are not reserved words and can be used as identifiers
T_ACTIVITY_COUNT
| T_ALL
+ | T_ALLOCATE
| T_ALTER
| T_AND
| T_AS
- | T_ASC
+ | T_ASC
+ | T_ASSOCIATE
| T_AT
| T_AVG
| T_BATCHSIZE
@@ -1004,6 +1020,8 @@ non_reserved_words : // Tokens that are not reserved words
| T_LIMIT
| T_LINES
| T_LOCAL
+ | T_LOCATOR
+ | T_LOCATORS
| T_LOGGED
| T_LOOP
| T_MAP
@@ -1042,6 +1060,7 @@ non_reserved_words : // Tokens that are not reserved words
| T_REPLACE
| T_RESIGNAL
| T_RESULT
+ | T_RESULT_SET_LOCATOR
| T_RETURN
| T_RETURNS
| T_REVERSE
@@ -1092,6 +1111,7 @@ non_reserved_words : // Tokens that are not reserved words
| T_VAR
| T_VARCHAR
| T_VARCHAR2
+ | T_VARYING
| T_VARIANCE
| T_VOLATILE
// T_WHEN reserved word
@@ -1104,10 +1124,12 @@ non_reserved_words : // Tokens that are not reserved words
// Lexer rules
T_ALL : A L L ;
+T_ALLOCATE : A L L O C A T E ;
T_ALTER : A L T E R ;
T_AND : A N D ;
T_AS : A S ;
T_ASC : A S C ;
+T_ASSOCIATE : A S S O C I A T E ;
T_AT : A T ;
T_AVG : A V G ;
T_BATCHSIZE : B A T C H S I Z E ;
@@ -1214,6 +1236,8 @@ T_LIKE : L I K E ;
T_LIMIT : L I M I T ;
T_LINES : L I N E S ;
T_LOCAL : L O C A L ;
+T_LOCATOR : L O C A T O R ;
+T_LOCATORS : L O C A T O R S ;
T_LOGGED : L O G G E D ;
T_LOOP : L O O P ;
T_MAP : M A P ;
@@ -1249,6 +1273,7 @@ T_REGEXP : R E G E X P ;
T_REPLACE : R E P L A C E ;
T_RESIGNAL : R E S I G N A L ;
T_RESULT : R E S U L T ;
+T_RESULT_SET_LOCATOR : R E S U L T '_' S E T '_' L O C A T O R ;
T_RETURN : R E T U R N ;
T_RETURNS : R E T U R N S ;
T_REVERSE : R E V E R S E ;
@@ -1296,6 +1321,7 @@ T_VALUES : V A L U E S ;
T_VAR : V A R ;
T_VARCHAR : V A R C H A R ;
T_VARCHAR2 : V A R C H A R '2' ;
+T_VARYING : V A R Y I N G ;
T_VOLATILE : V O L A T I L E ;
T_WHEN : W H E N ;
T_WHERE : W H E R E ;
diff --git hplsql/src/main/java/org/apache/hive/hplsql/Conn.java hplsql/src/main/java/org/apache/hive/hplsql/Conn.java
index 828fbc3..ac4b521 100644
--- hplsql/src/main/java/org/apache/hive/hplsql/Conn.java
+++ hplsql/src/main/java/org/apache/hive/hplsql/Conn.java
@@ -41,10 +41,12 @@
Exec exec;
Timer timer = new Timer();
boolean trace = false;
+ boolean info = false;
Conn(Exec e) {
exec = e;
trace = exec.getTrace();
+ info = exec.getInfo();
}
/**
@@ -59,8 +61,8 @@ public Query executeQuery(Query query, String connName) {
ResultSet rs = stmt.executeQuery(query.sql);
timer.stop();
query.set(conn, stmt, rs);
- if (trace) {
- exec.trace(null, "Query executed successfully (" + timer.format() + ")");
+ if (info) {
+ exec.info(null, "Query executed successfully (" + timer.format() + ")");
}
} catch (Exception e) {
query.setError(e);
@@ -169,8 +171,8 @@ Connection openConnection(String connStr) throws Exception {
timer.start();
Connection conn = DriverManager.getConnection(url, usr, pwd);
timer.stop();
- if (trace) {
- exec.trace(null, "Open connection: " + url + " (" + timer.format() + ")");
+ if (info) {
+ exec.info(null, "Open connection: " + url + " (" + timer.format() + ")");
}
return conn;
}
diff --git hplsql/src/main/java/org/apache/hive/hplsql/Exec.java hplsql/src/main/java/org/apache/hive/hplsql/Exec.java
index 40fdc82..b35344f 100644
--- hplsql/src/main/java/org/apache/hive/hplsql/Exec.java
+++ hplsql/src/main/java/org/apache/hive/hplsql/Exec.java
@@ -39,6 +39,7 @@
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ParseTree;
import org.apache.commons.io.FileUtils;
+import org.apache.hive.hplsql.Var.Type;
import org.apache.hive.hplsql.functions.*;
/**
@@ -63,6 +64,7 @@
Stack stack = new Stack();
Stack labels = new Stack();
+ Stack callStack = new Stack();
Stack signals = new Stack();
Signal currentSignal;
@@ -72,9 +74,10 @@
HashMap managedTables = new HashMap();
HashMap objectMap = new HashMap();
HashMap objectConnMap = new HashMap();
+ HashMap> returnCursors = new HashMap>();
public ArrayList stmtConnList = new ArrayList();
-
+
Arguments arguments = new Arguments();
public Conf conf;
Expression expr;
@@ -183,6 +186,32 @@ public void addHandler(Handler handler) {
}
/**
+ * Add a return cursor visible to procedure callers and clients
+ */
+ public void addReturnCursor(Var var) {
+ String routine = callStackPeek();
+ ArrayList cursors = returnCursors.get(routine);
+ if (cursors == null) {
+ cursors = new ArrayList();
+ returnCursors.put(routine, cursors);
+ }
+ cursors.add(var);
+ }
+
+ /**
+ * Get the return cursor defined in the specified procedure
+ */
+ public Var consumeReturnCursor(String routine) {
+ ArrayList cursors = returnCursors.get(routine.toUpperCase());
+ if (cursors == null) {
+ return null;
+ }
+ Var var = cursors.get(0);
+ cursors.remove(0);
+ return var;
+ }
+
+ /**
* Push a value to the stack
*/
public void stackPush(Var var) {
@@ -224,6 +253,33 @@ public Var stackPop() {
return null;
}
+ /**
+ * Push a value to the call stack
+ */
+ public void callStackPush(String val) {
+ exec.callStack.push(val.toUpperCase());
+ }
+
+ /**
+ * Select a value from the call stack, but not remove
+ */
+ public String callStackPeek() {
+ if (!exec.callStack.isEmpty()) {
+ return exec.callStack.peek();
+ }
+ return null;
+ }
+
+ /**
+ * Pop a value from the call stack
+ */
+ public String callStackPop() {
+ if (!exec.callStack.isEmpty()) {
+ return exec.callStack.pop();
+ }
+ return null;
+ }
+
/**
* Find an existing variable by name
*/
@@ -250,6 +306,17 @@ public Var findVariable(Var name) {
}
/**
+ * Find a cursor variable by name
+ */
+ public Var findCursor(String name) {
+ Var cursor = exec.findVariable(name);
+ if (cursor != null && cursor.type == Type.CURSOR) {
+ return cursor;
+ }
+ return null;
+ }
+
+ /**
* Enter a new scope
*/
public void enterScope(Scope.Type type) {
@@ -286,10 +353,12 @@ public void signal(Signal.Type type, String value, Exception exception) {
}
public void signal(Signal.Type type, String value) {
+ setSqlCode(-1);
signal(type, value, null);
}
public void signal(Signal.Type type) {
+ setSqlCode(-1);
signal(type, null, null);
}
@@ -480,20 +549,20 @@ void initOptions() {
Entry item = (Entry)i.next();
String key = (String)item.getKey();
String value = (String)item.getValue();
- if (key == null || value == null) {
+ if (key == null || value == null || !key.startsWith("hplsql.")) {
continue;
}
else if (key.compareToIgnoreCase(Conf.CONN_DEFAULT) == 0) {
exec.conf.defaultConnection = value;
}
else if (key.startsWith("hplsql.conn.init.")) {
- exec.conn.addConnectionInit(key.substring(16), value);
+ exec.conn.addConnectionInit(key.substring(17), value);
}
else if (key.startsWith(Conf.CONN_CONVERT)) {
- exec.conf.setConnectionConvert(key.substring(19), value);
+ exec.conf.setConnectionConvert(key.substring(20), value);
}
else if (key.startsWith("hplsql.conn.")) {
- exec.conn.addConnection(key.substring(11), value);
+ exec.conn.addConnection(key.substring(12), value);
}
else if (key.startsWith("hplsql.")) {
exec.conf.setOption(key, value);
@@ -940,7 +1009,7 @@ public Integer visitException_block_item(HplsqlParser.Exception_block_itemContex
*/
@Override
public Integer visitDeclare_var_item(HplsqlParser.Declare_var_itemContext ctx) {
- String type = ctx.dtype().getText();
+ String type = getFormattedText(ctx.dtype());
String len = null;
String scale = null;
Var default_ = null;
@@ -969,6 +1038,22 @@ public Integer visitDeclare_var_item(HplsqlParser.Declare_var_itemContext ctx) {
}
return 0;
}
+
+ /**
+ * ALLOCATE CURSOR statement
+ */
+ @Override
+ public Integer visitAllocate_cursor_stmt(HplsqlParser.Allocate_cursor_stmtContext ctx) {
+ return exec.stmt.allocateCursor(ctx);
+ }
+
+ /**
+ * ASSOCIATE LOCATOR statement
+ */
+ @Override
+ public Integer visitAssociate_locator_stmt(HplsqlParser.Associate_locator_stmtContext ctx) {
+ return exec.stmt.associateLocator(ctx);
+ }
/**
* DECLARE cursor statement
diff --git hplsql/src/main/java/org/apache/hive/hplsql/Query.java hplsql/src/main/java/org/apache/hive/hplsql/Query.java
index 23d963f..eaaaa67 100644
--- hplsql/src/main/java/org/apache/hive/hplsql/Query.java
+++ hplsql/src/main/java/org/apache/hive/hplsql/Query.java
@@ -35,6 +35,8 @@
ResultSet rs;
Exception exception;
+ boolean withReturn = false;
+
Query() {
}
@@ -103,6 +105,13 @@ public void setSelectCtx(ParserRuleContext sqlSelect) {
}
/**
+ * Set whether the cursor is returned to the caller
+ */
+ public void setWithReturn(boolean withReturn) {
+ this.withReturn = withReturn;
+ }
+
+ /**
* Set an execution error
*/
public void setError(Exception e) {
@@ -133,6 +142,13 @@ public Connection getConnection() {
}
/**
+ * Check if the cursor defined as a return cursor to client
+ */
+ public boolean getWithReturn() {
+ return withReturn;
+ }
+
+ /**
* Return error information
*/
public boolean error() {
diff --git hplsql/src/main/java/org/apache/hive/hplsql/Stmt.java hplsql/src/main/java/org/apache/hive/hplsql/Stmt.java
index acc4907..bfb76cd 100644
--- hplsql/src/main/java/org/apache/hive/hplsql/Stmt.java
+++ hplsql/src/main/java/org/apache/hive/hplsql/Stmt.java
@@ -48,6 +48,58 @@
}
/**
+ * ALLOCATE CURSOR statement
+ */
+ public Integer allocateCursor(HplsqlParser.Allocate_cursor_stmtContext ctx) {
+ trace(ctx, "ALLOCATE CURSOR");
+ String name = ctx.ident(0).getText();
+ Var cur = null;
+ if (ctx.T_PROCEDURE() != null) {
+ cur = exec.consumeReturnCursor(ctx.ident(1).getText());
+ }
+ else if (ctx.T_RESULT() != null) {
+ cur = exec.findVariable(ctx.ident(1).getText());
+ if (cur != null && cur.type != Type.RS_LOCATOR) {
+ cur = null;
+ }
+ }
+ if (cur == null) {
+ trace(ctx, "Cursor for procedure not found: " + name);
+ exec.signal(Signal.Type.SQLEXCEPTION);
+ return -1;
+ }
+ exec.addVariable(new Var(name, Type.CURSOR, cur.value));
+ return 0;
+ }
+
+ /**
+ * ASSOCIATE LOCATOR statement
+ */
+ public Integer associateLocator(HplsqlParser.Associate_locator_stmtContext ctx) {
+ trace(ctx, "ASSOCIATE LOCATOR");
+ int cnt = ctx.ident().size();
+ if (cnt < 2) {
+ return -1;
+ }
+ String procedure = ctx.ident(cnt - 1).getText();
+ for (int i = 0; i < cnt - 1; i++) {
+ Var cur = exec.consumeReturnCursor(procedure);
+ if (cur != null) {
+ String name = ctx.ident(i).getText();
+ Var loc = exec.findVariable(name);
+ if (loc == null) {
+ loc = new Var(name, Type.RS_LOCATOR, cur.value);
+ exec.addVariable(loc);
+ }
+ else {
+ loc.setValue(cur.value);
+ }
+ }
+ }
+ return 0;
+ }
+
+ /**
* DECLARE cursor statement
*/
public Integer declareCursor(HplsqlParser.Declare_cursor_itemContext ctx) {
@@ -62,7 +114,11 @@ public Integer declareCursor(HplsqlParser.Declare_cursor_itemContext ctx) {
else if (ctx.select_stmt() != null) {
query.setSelectCtx(ctx.select_stmt());
}
- exec.addVariable(new Var(name, Type.CURSOR, query));
+ if (ctx.cursor_with_return() != null) {
+ query.setWithReturn(true);
+ }
+ Var var = new Var(name, Type.CURSOR, query);
+ exec.addVariable(var);
return 0;
}
@@ -262,6 +318,9 @@ else if (query.sqlSelect != null) {
else if (!exec.getOffline()) {
exec.setSqlCode(0);
}
+ if (query.getWithReturn()) {
+ exec.addReturnCursor(var);
+ }
}
else {
trace(ctx, "Cursor not found: " + cursor);
@@ -278,8 +337,8 @@ else if (!exec.getOffline()) {
public Integer fetch(HplsqlParser.Fetch_stmtContext ctx) {
trace(ctx, "FETCH");
String name = ctx.L_ID(0).toString();
- Var cursor = exec.findVariable(name);
- if (cursor == null || cursor.type != Type.CURSOR) {
+ Var cursor = exec.findCursor(name);
+ if (cursor == null) {
trace(ctx, "Cursor not found: " + name);
exec.setSqlCode(-1);
exec.signal(Signal.Type.SQLEXCEPTION);
@@ -319,9 +378,11 @@ else if(trace) {
}
else {
exec.setSqlCode(100);
- exec.signal(Signal.Type.NOTFOUND);
}
}
+ else {
+ exec.setSqlCode(-1);
+ }
}
catch (SQLException e) {
exec.setSqlCode(e);
diff --git hplsql/src/main/java/org/apache/hive/hplsql/Utils.java hplsql/src/main/java/org/apache/hive/hplsql/Utils.java
index da0d878..1815deb 100644
--- hplsql/src/main/java/org/apache/hive/hplsql/Utils.java
+++ hplsql/src/main/java/org/apache/hive/hplsql/Utils.java
@@ -286,4 +286,11 @@ public static String formatBytesPerSec(long bytes, long msElapsed) {
float bytesPerSec = ((float)bytes)/msElapsed*1000;
return Utils.formatSizeInBytes((long)bytesPerSec, "/sec");
}
+
+ /**
+ * Note. This stub is to resolve name conflict with ANTLR generated source using org.antlr.v4.runtime.misc.Utils.join
+ */
+ static String join(T[] array, String separator) {
+ return org.antlr.v4.runtime.misc.Utils.join(array, separator);
+ }
}
diff --git hplsql/src/main/java/org/apache/hive/hplsql/Var.java hplsql/src/main/java/org/apache/hive/hplsql/Var.java
index 0a4ead2..87b42f9 100644
--- hplsql/src/main/java/org/apache/hive/hplsql/Var.java
+++ hplsql/src/main/java/org/apache/hive/hplsql/Var.java
@@ -32,7 +32,7 @@
public class Var {
// Data types
- public enum Type {BOOL, CURSOR, DATE, DEC, FILE, IDENT, BIGINT, INTERVAL, STRING, STRINGLIST, TIMESTAMP, NULL};
+ public enum Type {BOOL, CURSOR, DATE, DEC, FILE, IDENT, BIGINT, INTERVAL, RS_LOCATOR, STRING, STRINGLIST, TIMESTAMP, NULL};
public static Var Empty = new Var();
public static Var Null = new Var(Type.NULL);
@@ -194,6 +194,10 @@ public Var setValue(Long val) {
return this;
}
+ public void setValue(Object value) {
+ this.value = value;
+ }
+
/**
* Set the new value from a result set
*/
@@ -244,6 +248,9 @@ else if (type.equalsIgnoreCase("TIMESTAMP")) {
else if (type.equalsIgnoreCase("UTL_FILE.FILE_TYPE")) {
return Type.FILE;
}
+ else if (type.toUpperCase().startsWith("RESULT_SET_LOCATOR")) {
+ return Type.RS_LOCATOR;
+ }
return Type.NULL;
}
diff --git hplsql/src/main/java/org/apache/hive/hplsql/functions/Function.java hplsql/src/main/java/org/apache/hive/hplsql/functions/Function.java
index 9895b5e..394598b 100644
--- hplsql/src/main/java/org/apache/hive/hplsql/functions/Function.java
+++ hplsql/src/main/java/org/apache/hive/hplsql/functions/Function.java
@@ -188,8 +188,12 @@ public boolean execProc(String name) {
return false;
}
exec.enterScope(Scope.Type.ROUTINE);
- setCallParameters(procCtx.create_routine_params());
+ exec.callStackPush(name);
+ if (procCtx.create_routine_params() != null) {
+ setCallParameters(procCtx.create_routine_params());
+ }
visit(procCtx.single_block_stmt());
+ exec.callStackPop();
exec.leaveScope();
return true;
}
@@ -208,8 +212,12 @@ public boolean execProc(HplsqlParser.Expr_func_paramsContext ctx, String name) {
}
HashMap out = new HashMap();
exec.enterScope(Scope.Type.ROUTINE);
- setCallParameters(ctx, procCtx.create_routine_params(), out);
+ exec.callStackPush(name);
+ if (procCtx.create_routine_params() != null) {
+ setCallParameters(ctx, procCtx.create_routine_params(), out);
+ }
visit(procCtx.single_block_stmt());
+ exec.callStackPop();
exec.leaveScope();
for (Map.Entry i : out.entrySet()) { // Set OUT parameters
exec.setVariable(i.getKey(), i.getValue());
diff --git hplsql/src/main/resources/hplsql-site.xml hplsql/src/main/resources/hplsql-site.xml
new file mode 100644
index 0000000..1a3202a
--- /dev/null
+++ hplsql/src/main/resources/hplsql-site.xml
@@ -0,0 +1,95 @@
+
+
+ hplsql.conn.default
+ hiveconn
+ The default connection profile
+
+
+ hplsql.conn.hiveconn
+ org.apache.hive.jdbc.HiveDriver;jdbc:hive2://
+ HiveServer2 JDBC connection (embedded mode)
+
+
+ hplsql.conn.init.hiveconn
+
+ set mapred.job.queue.name=default;
+ set hive.execution.engine=mr;
+ use default;
+
+ Statements for execute after connection to the database
+
+
+ hplsql.conn.convert.hiveconn
+ true
+ Convert SQL statements before execution
+
+
+ hplsql.conn.hive1conn
+ org.apache.hadoop.hive.jdbc.HiveDriver;jdbc:hive://
+ Hive embedded JDBC (not requiring HiveServer)
+
+
+ hplsql.conn.hive2conn
+ org.apache.hive.jdbc.HiveDriver;jdbc:hive2://localhost:10000;hive;hive
+ HiveServer2 JDBC connection
+
+
+ hplsql.conn.init.hive2conn
+
+ set mapred.job.queue.name=default;
+ set hive.execution.engine=mr;
+ use default;
+
+ Statements for execute after connection to the database
+
+
+ hplsql.conn.convert.hive2conn
+ true
+ Convert SQL statements before execution
+
+
+ hplsql.conn.db2conn
+ com.ibm.db2.jcc.DB2Driver;jdbc:db2://localhost:50001/dbname;user;password
+ IBM DB2 connection
+
+
+ hplsql.conn.tdconn
+ com.teradata.jdbc.TeraDriver;jdbc:teradata://localhost/database=dbname,logmech=ldap;user;password
+ Teradata connection
+
+
+ hplsql.conn.mysqlconn
+ com.mysql.jdbc.Driver;jdbc:mysql://localhost/test;user;password
+ MySQL connection
+
+
+ hplsql.dual.table
+ default.dual
+ Single row, single column table for internal operations
+
+
+ hplsql.insert.values
+ native
+ How to execute INSERT VALUES statement: native (default) and select
+
+
+ hplsql.onerror
+ exception
+ Error handling behavior: exception (default), seterror and stop
+
+
+ hplsql.temp.tables
+ native
+ Temporary tables: native (default) and managed
+
+
+ hplsql.temp.tables.schema
+
+ Schema for managed temporary tables
+
+
+ hplsql.temp.tables.location
+ /tmp/plhql
+ LOcation for managed temporary tables in HDFS
+
+
\ No newline at end of file
diff --git hplsql/src/test/java/org/apache/hive/hplsql/TestHplsqlLocal.java hplsql/src/test/java/org/apache/hive/hplsql/TestHplsqlLocal.java
index ee2be66..5ec91d9 100644
--- hplsql/src/test/java/org/apache/hive/hplsql/TestHplsqlLocal.java
+++ hplsql/src/test/java/org/apache/hive/hplsql/TestHplsqlLocal.java
@@ -134,26 +134,6 @@ public void testException() throws Exception {
}
@Test
- public void testException2() throws Exception {
- run("exception2");
- }
-
- @Test
- public void testException3() throws Exception {
- run("exception2");
- }
-
- @Test
- public void testException4() throws Exception {
- run("exception2");
- }
-
- @Test
- public void testException5() throws Exception {
- run("exception2");
- }
-
- @Test
public void testExit() throws Exception {
run("exit");
}
@@ -300,11 +280,7 @@ void run(String testFile) throws Exception {
System.setOut(new PrintStream(out));
Exec exec = new Exec();
String[] args = { "-f", "src/test/queries/local/" + testFile + ".sql", "-trace" };
- exec.init(args);
- Var result = exec.run();
- if (result != null) {
- System.out.println(result.toString());
- }
+ exec.run(args);
String s = getTestOutput(out.toString()).trim();
FileUtils.writeStringToFile(new java.io.File("target/tmp/log/" + testFile + ".out.txt"), s);
String t = FileUtils.readFileToString(new java.io.File("src/test/results/local/" + testFile + ".out.txt"), "utf-8").trim();
diff --git hplsql/src/test/queries/db/create_procedure_return_cursor.sql hplsql/src/test/queries/db/create_procedure_return_cursor.sql
new file mode 100644
index 0000000..d954863
--- /dev/null
+++ hplsql/src/test/queries/db/create_procedure_return_cursor.sql
@@ -0,0 +1,53 @@
+CREATE PROCEDURE spResultSet1
+ DYNAMIC RESULT SETS 1
+BEGIN
+ DECLARE cur1 CURSOR WITH RETURN FOR
+ SELECT 'A', 'A1' FROM src LIMIT 3;
+ OPEN cur1;
+END;
+
+CREATE PROCEDURE spResultSet2
+ DYNAMIC RESULT SETS 2
+BEGIN
+ DECLARE cur1 CURSOR WITH RETURN FOR
+ SELECT 'B', 'B1' FROM src LIMIT 5;
+ DECLARE cur2 CURSOR WITH RETURN FOR
+ SELECT 'C', 'C1' FROM src LIMIT 7;
+ OPEN cur1;
+ OPEN cur2;
+END;
+
+DECLARE v1 VARCHAR(10);
+DECLARE v2 VARCHAR(10);
+
+CALL spResultSet1;
+ALLOCATE c1 CURSOR FOR PROCEDURE spResultSet1;
+
+FETCH c1 INTO v1, v2;
+WHILE (SQLCODE = 0)
+DO
+ PRINT v1 || ' - ' || v2;
+ FETCH c1 INTO v1, v2;
+END WHILE;
+CLOSE c1;
+
+CALL spResultSet2;
+ALLOCATE c2 CURSOR FOR PROCEDURE spResultSet2;
+
+FETCH c2 INTO v1, v2;
+WHILE (SQLCODE = 0)
+DO
+ PRINT v1 || ' - ' || v2;
+ FETCH c2 INTO v1, v2;
+END WHILE;
+CLOSE c2;
+
+ALLOCATE c3 CURSOR FOR PROCEDURE spResultSet2;
+
+FETCH c3 INTO v1, v2;
+WHILE (SQLCODE = 0)
+DO
+ PRINT v1 || ' - ' || v2;
+ FETCH c3 INTO v1, v2;
+END WHILE;
+CLOSE c3;
diff --git hplsql/src/test/queries/db/create_procedure_return_cursor2.sql hplsql/src/test/queries/db/create_procedure_return_cursor2.sql
new file mode 100644
index 0000000..a9a1ffe
--- /dev/null
+++ hplsql/src/test/queries/db/create_procedure_return_cursor2.sql
@@ -0,0 +1,59 @@
+CREATE PROCEDURE spResultSet1
+ DYNAMIC RESULT SETS 1
+BEGIN
+ DECLARE cur1 CURSOR WITH RETURN FOR
+ SELECT 'A', 'A1' FROM src LIMIT 3;
+ OPEN cur1;
+END;
+
+CREATE PROCEDURE spResultSet2
+ DYNAMIC RESULT SETS 2
+BEGIN
+ DECLARE cur1 CURSOR WITH RETURN FOR
+ SELECT 'B', 'B1' FROM src LIMIT 5;
+ DECLARE cur2 CURSOR WITH RETURN FOR
+ SELECT 'C', 'C1' FROM src LIMIT 7;
+ OPEN cur1;
+ OPEN cur2;
+END;
+
+DECLARE v1 VARCHAR(10);
+DECLARE v2 VARCHAR(10);
+DECLARE loc1 RESULT_SET_LOCATOR VARYING;
+DECLARE loc2 RESULT_SET_LOCATOR VARYING;
+
+CALL spResultSet1;
+
+ASSOCIATE RESULT SET LOCATOR (loc1) WITH PROCEDURE spResultSet1;
+ALLOCATE c1 CURSOR FOR RESULT SET loc1;
+
+FETCH c1 INTO v1, v2;
+WHILE (SQLCODE = 0)
+DO
+ PRINT v1 || ' - ' || v2;
+ FETCH c1 INTO v1, v2;
+END WHILE;
+CLOSE c1;
+
+CALL spResultSet2;
+
+ASSOCIATE RESULT SET LOCATOR (loc1, loc2) WITH PROCEDURE spResultSet2;
+ALLOCATE c2 CURSOR FOR RESULT SET loc1;
+
+FETCH c2 INTO v1, v2;
+WHILE (SQLCODE = 0)
+DO
+ PRINT v1 || ' - ' || v2;
+ FETCH c2 INTO v1, v2;
+END WHILE;
+CLOSE c2;
+
+ALLOCATE c3 CURSOR FOR RESULT SET loc2;
+
+FETCH c3 INTO v1, v2;
+WHILE (SQLCODE = 0)
+DO
+ PRINT v1 || ' - ' || v2;
+ FETCH c3 INTO v1, v2;
+END WHILE;
+CLOSE c3;
diff --git hplsql/src/test/queries/local/exception2.sql hplsql/src/test/queries/local/exception2.sql
deleted file mode 100644
index 3394da8..0000000
--- hplsql/src/test/queries/local/exception2.sql
+++ /dev/null
@@ -1,10 +0,0 @@
-DECLARE
- v VARCHAR(200);
-BEGIN
- OPEN cur FOR 'SELECT c1 FROM t1';
- FETCH cur INTO v;
- CLOSE cur;
-EXCEPTION WHEN OTHERS THEN
- DBMS_OUTPUT.PUT_LINE('Error');
-END
-
diff --git hplsql/src/test/queries/local/exception3.sql hplsql/src/test/queries/local/exception3.sql
deleted file mode 100644
index a12b853..0000000
--- hplsql/src/test/queries/local/exception3.sql
+++ /dev/null
@@ -1,5 +0,0 @@
-PRINT 'Correct';
-WHILE 1=1 THEN
-FETCH cur INTO v;
-PRINT 'Incorrect - unreachable code, unknown cursor name, exception must be raised';
-END WHILE;
diff --git hplsql/src/test/queries/local/exception4.sql hplsql/src/test/queries/local/exception4.sql
deleted file mode 100644
index 38d89b5..0000000
--- hplsql/src/test/queries/local/exception4.sql
+++ /dev/null
@@ -1,7 +0,0 @@
-PRINT 'Correct';
-DECLARE EXIT HANDLER FOR SQLEXCEPTION
- PRINT 'Correct - Exception raised';
-WHILE 1=1 THEN
-FETCH cur INTO v;
-PRINT 'Incorrect - unreachable code, unknown cursor name, exception must be raised';
-END WHILE;
diff --git hplsql/src/test/queries/local/exception5.sql hplsql/src/test/queries/local/exception5.sql
deleted file mode 100644
index 6232984..0000000
--- hplsql/src/test/queries/local/exception5.sql
+++ /dev/null
@@ -1,10 +0,0 @@
-DECLARE cnt INT := 0;
-PRINT 'Correct';
-DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
- PRINT 'Correct - Exception raised';
-WHILE cnt < 10 THEN
-FETCH cur INTO v;
-PRINT cnt;
-PRINT 'Correct - exception handled';
-SET cnt = cnt + 1;
-END WHILE;
diff --git hplsql/src/test/results/db/create_procedure_return_cursor.out.txt hplsql/src/test/results/db/create_procedure_return_cursor.out.txt
new file mode 100644
index 0000000..81aa6c8
--- /dev/null
+++ hplsql/src/test/results/db/create_procedure_return_cursor.out.txt
@@ -0,0 +1,135 @@
+Ln:1 CREATE PROCEDURE spResultSet1
+Ln:9 CREATE PROCEDURE spResultSet2
+Ln:20 DECLARE v1 VARCHAR
+Ln:21 DECLARE v2 VARCHAR
+EXEC PROCEDURE spResultSet1
+Ln:4 DECLARE CURSOR cur1
+Ln:6 OPEN
+Ln:6 cur1: SELECT 'A', 'A1' FROM src LIMIT 3
+Ln:24 ALLOCATE CURSOR
+Ln:26 FETCH
+Ln:26 COLUMN: _c0, string
+Ln:26 SET v1 = A
+Ln:26 COLUMN: _c1, string
+Ln:26 SET v2 = A1
+Ln:27 WHILE - ENTERED
+Ln:29 PRINT
+A - A1
+Ln:30 FETCH
+Ln:30 COLUMN: _c0, string
+Ln:30 SET v1 = A
+Ln:30 COLUMN: _c1, string
+Ln:30 SET v2 = A1
+Ln:29 PRINT
+A - A1
+Ln:30 FETCH
+Ln:30 COLUMN: _c0, string
+Ln:30 SET v1 = A
+Ln:30 COLUMN: _c1, string
+Ln:30 SET v2 = A1
+Ln:29 PRINT
+A - A1
+Ln:30 FETCH
+Ln:27 WHILE - LEFT
+Ln:32 CLOSE
+EXEC PROCEDURE spResultSet2
+Ln:12 DECLARE CURSOR cur1
+Ln:14 DECLARE CURSOR cur2
+Ln:16 OPEN
+Ln:16 cur1: SELECT 'B', 'B1' FROM src LIMIT 5
+Ln:17 OPEN
+Ln:17 cur2: SELECT 'C', 'C1' FROM src LIMIT 7
+Ln:35 ALLOCATE CURSOR
+Ln:37 FETCH
+Ln:37 COLUMN: _c0, string
+Ln:37 SET v1 = B
+Ln:37 COLUMN: _c1, string
+Ln:37 SET v2 = B1
+Ln:38 WHILE - ENTERED
+Ln:40 PRINT
+B - B1
+Ln:41 FETCH
+Ln:41 COLUMN: _c0, string
+Ln:41 SET v1 = B
+Ln:41 COLUMN: _c1, string
+Ln:41 SET v2 = B1
+Ln:40 PRINT
+B - B1
+Ln:41 FETCH
+Ln:41 COLUMN: _c0, string
+Ln:41 SET v1 = B
+Ln:41 COLUMN: _c1, string
+Ln:41 SET v2 = B1
+Ln:40 PRINT
+B - B1
+Ln:41 FETCH
+Ln:41 COLUMN: _c0, string
+Ln:41 SET v1 = B
+Ln:41 COLUMN: _c1, string
+Ln:41 SET v2 = B1
+Ln:40 PRINT
+B - B1
+Ln:41 FETCH
+Ln:41 COLUMN: _c0, string
+Ln:41 SET v1 = B
+Ln:41 COLUMN: _c1, string
+Ln:41 SET v2 = B1
+Ln:40 PRINT
+B - B1
+Ln:41 FETCH
+Ln:38 WHILE - LEFT
+Ln:43 CLOSE
+Ln:45 ALLOCATE CURSOR
+Ln:47 FETCH
+Ln:47 COLUMN: _c0, string
+Ln:47 SET v1 = C
+Ln:47 COLUMN: _c1, string
+Ln:47 SET v2 = C1
+Ln:48 WHILE - ENTERED
+Ln:50 PRINT
+C - C1
+Ln:51 FETCH
+Ln:51 COLUMN: _c0, string
+Ln:51 SET v1 = C
+Ln:51 COLUMN: _c1, string
+Ln:51 SET v2 = C1
+Ln:50 PRINT
+C - C1
+Ln:51 FETCH
+Ln:51 COLUMN: _c0, string
+Ln:51 SET v1 = C
+Ln:51 COLUMN: _c1, string
+Ln:51 SET v2 = C1
+Ln:50 PRINT
+C - C1
+Ln:51 FETCH
+Ln:51 COLUMN: _c0, string
+Ln:51 SET v1 = C
+Ln:51 COLUMN: _c1, string
+Ln:51 SET v2 = C1
+Ln:50 PRINT
+C - C1
+Ln:51 FETCH
+Ln:51 COLUMN: _c0, string
+Ln:51 SET v1 = C
+Ln:51 COLUMN: _c1, string
+Ln:51 SET v2 = C1
+Ln:50 PRINT
+C - C1
+Ln:51 FETCH
+Ln:51 COLUMN: _c0, string
+Ln:51 SET v1 = C
+Ln:51 COLUMN: _c1, string
+Ln:51 SET v2 = C1
+Ln:50 PRINT
+C - C1
+Ln:51 FETCH
+Ln:51 COLUMN: _c0, string
+Ln:51 SET v1 = C
+Ln:51 COLUMN: _c1, string
+Ln:51 SET v2 = C1
+Ln:50 PRINT
+C - C1
+Ln:51 FETCH
+Ln:48 WHILE - LEFT
+Ln:53 CLOSE
\ No newline at end of file
diff --git hplsql/src/test/results/db/create_procedure_return_cursor2.out.txt hplsql/src/test/results/db/create_procedure_return_cursor2.out.txt
new file mode 100644
index 0000000..40f2c33
--- /dev/null
+++ hplsql/src/test/results/db/create_procedure_return_cursor2.out.txt
@@ -0,0 +1,139 @@
+Ln:1 CREATE PROCEDURE spResultSet1
+Ln:9 CREATE PROCEDURE spResultSet2
+Ln:20 DECLARE v1 VARCHAR
+Ln:21 DECLARE v2 VARCHAR
+Ln:22 DECLARE loc1 RESULT_SET_LOCATOR VARYING
+Ln:23 DECLARE loc2 RESULT_SET_LOCATOR VARYING
+EXEC PROCEDURE spResultSet1
+Ln:4 DECLARE CURSOR cur1
+Ln:6 OPEN
+Ln:6 cur1: SELECT 'A', 'A1' FROM src LIMIT 3
+Ln:27 ASSOCIATE LOCATOR
+Ln:28 ALLOCATE CURSOR
+Ln:30 FETCH
+Ln:30 COLUMN: _c0, string
+Ln:30 SET v1 = A
+Ln:30 COLUMN: _c1, string
+Ln:30 SET v2 = A1
+Ln:31 WHILE - ENTERED
+Ln:33 PRINT
+A - A1
+Ln:34 FETCH
+Ln:34 COLUMN: _c0, string
+Ln:34 SET v1 = A
+Ln:34 COLUMN: _c1, string
+Ln:34 SET v2 = A1
+Ln:33 PRINT
+A - A1
+Ln:34 FETCH
+Ln:34 COLUMN: _c0, string
+Ln:34 SET v1 = A
+Ln:34 COLUMN: _c1, string
+Ln:34 SET v2 = A1
+Ln:33 PRINT
+A - A1
+Ln:34 FETCH
+Ln:31 WHILE - LEFT
+Ln:36 CLOSE
+EXEC PROCEDURE spResultSet2
+Ln:12 DECLARE CURSOR cur1
+Ln:14 DECLARE CURSOR cur2
+Ln:16 OPEN
+Ln:16 cur1: SELECT 'B', 'B1' FROM src LIMIT 5
+Ln:17 OPEN
+Ln:17 cur2: SELECT 'C', 'C1' FROM src LIMIT 7
+Ln:40 ASSOCIATE LOCATOR
+Ln:41 ALLOCATE CURSOR
+Ln:43 FETCH
+Ln:43 COLUMN: _c0, string
+Ln:43 SET v1 = B
+Ln:43 COLUMN: _c1, string
+Ln:43 SET v2 = B1
+Ln:44 WHILE - ENTERED
+Ln:46 PRINT
+B - B1
+Ln:47 FETCH
+Ln:47 COLUMN: _c0, string
+Ln:47 SET v1 = B
+Ln:47 COLUMN: _c1, string
+Ln:47 SET v2 = B1
+Ln:46 PRINT
+B - B1
+Ln:47 FETCH
+Ln:47 COLUMN: _c0, string
+Ln:47 SET v1 = B
+Ln:47 COLUMN: _c1, string
+Ln:47 SET v2 = B1
+Ln:46 PRINT
+B - B1
+Ln:47 FETCH
+Ln:47 COLUMN: _c0, string
+Ln:47 SET v1 = B
+Ln:47 COLUMN: _c1, string
+Ln:47 SET v2 = B1
+Ln:46 PRINT
+B - B1
+Ln:47 FETCH
+Ln:47 COLUMN: _c0, string
+Ln:47 SET v1 = B
+Ln:47 COLUMN: _c1, string
+Ln:47 SET v2 = B1
+Ln:46 PRINT
+B - B1
+Ln:47 FETCH
+Ln:44 WHILE - LEFT
+Ln:49 CLOSE
+Ln:51 ALLOCATE CURSOR
+Ln:53 FETCH
+Ln:53 COLUMN: _c0, string
+Ln:53 SET v1 = C
+Ln:53 COLUMN: _c1, string
+Ln:53 SET v2 = C1
+Ln:54 WHILE - ENTERED
+Ln:56 PRINT
+C - C1
+Ln:57 FETCH
+Ln:57 COLUMN: _c0, string
+Ln:57 SET v1 = C
+Ln:57 COLUMN: _c1, string
+Ln:57 SET v2 = C1
+Ln:56 PRINT
+C - C1
+Ln:57 FETCH
+Ln:57 COLUMN: _c0, string
+Ln:57 SET v1 = C
+Ln:57 COLUMN: _c1, string
+Ln:57 SET v2 = C1
+Ln:56 PRINT
+C - C1
+Ln:57 FETCH
+Ln:57 COLUMN: _c0, string
+Ln:57 SET v1 = C
+Ln:57 COLUMN: _c1, string
+Ln:57 SET v2 = C1
+Ln:56 PRINT
+C - C1
+Ln:57 FETCH
+Ln:57 COLUMN: _c0, string
+Ln:57 SET v1 = C
+Ln:57 COLUMN: _c1, string
+Ln:57 SET v2 = C1
+Ln:56 PRINT
+C - C1
+Ln:57 FETCH
+Ln:57 COLUMN: _c0, string
+Ln:57 SET v1 = C
+Ln:57 COLUMN: _c1, string
+Ln:57 SET v2 = C1
+Ln:56 PRINT
+C - C1
+Ln:57 FETCH
+Ln:57 COLUMN: _c0, string
+Ln:57 SET v1 = C
+Ln:57 COLUMN: _c1, string
+Ln:57 SET v2 = C1
+Ln:56 PRINT
+C - C1
+Ln:57 FETCH
+Ln:54 WHILE - LEFT
+Ln:59 CLOSE
\ No newline at end of file