@Override public ReferenceCollection getReferences(Var var) { if (!var.isGlobal()) { return null; } return refMap.get(var.getName()); }
/** EXEC, EXECUTE and EXECUTE IMMEDIATE statement to execute dynamic SQL */ public Integer exec(HplsqlParser.Exec_stmtContext ctx) { if (trace) { trace(ctx, "EXECUTE"); } Var vsql = evalPop(ctx.expr()); String sql = vsql.toString(); if (trace) { trace(ctx, "Query: " + sql); } Query query = exec.executeSql(ctx, sql, exec.conf.defaultConnection); if (query.error()) { exec.signal(query); return 1; } ResultSet rs = query.getResultSet(); if (rs != null) { try { ResultSetMetaData rsm = rs.getMetaData(); // Assign to variables if (ctx.T_INTO() != null) { int cols = ctx.L_ID().size(); if (rs.next()) { for (int i = 0; i < cols; i++) { Var var = exec.findVariable(ctx.L_ID(i).getText()); if (var != null) { var.setValue(rs, rsm, i + 1); if (trace) { trace( ctx, "COLUMN: " + rsm.getColumnName(i + 1) + ", " + rsm.getColumnTypeName(i + 1)); trace(ctx, "SET " + var.getName() + " = " + var.toString()); } } else if (trace) { trace(ctx, "Variable not found: " + ctx.L_ID(i).getText()); } } exec.setSqlCode(0); } } // Print the results else { int cols = rsm.getColumnCount(); while (rs.next()) { for (int i = 1; i <= cols; i++) { if (i > 1) { System.out.print("\t"); } System.out.print(rs.getString(i)); } System.out.println(""); } } } catch (SQLException e) { exec.setSqlCode(e); } } exec.closeQuery(query, exec.conf.defaultConnection); return 0; }
/** * Resets global var reference map with the new provide map. * * @param globalRefMap The reference map result of a {@link ReferenceCollectingCallback} pass * collected from the whole AST. */ private void resetGlobalVarReferences(Map<Var, ReferenceCollection> globalRefMap) { refMap = new HashMap<>(); for (Entry<Var, ReferenceCollection> entry : globalRefMap.entrySet()) { Var var = entry.getKey(); if (var.isGlobal()) { refMap.put(var.getName(), entry.getValue()); } } }
/** FETCH cursor statement */ 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) { trace(ctx, "Cursor not found: " + name); exec.setSqlCode(-1); exec.signal(Signal.Type.SQLEXCEPTION); return 1; } else if (exec.getOffline()) { exec.setSqlCode(100); exec.signal(Signal.Type.NOTFOUND); return 0; } // Assign values from the row to local variables try { Query query = (Query) cursor.value; ResultSet rs = query.getResultSet(); ResultSetMetaData rsm = null; if (rs != null) { rsm = rs.getMetaData(); } if (rs != null && rsm != null) { int cols = ctx.L_ID().size() - 1; if (rs.next()) { for (int i = 1; i <= cols; i++) { Var var = exec.findVariable(ctx.L_ID(i).getText()); if (var != null) { var.setValue(rs, rsm, i); if (trace) { trace(ctx, "COLUMN: " + rsm.getColumnName(i) + ", " + rsm.getColumnTypeName(i)); trace(ctx, "SET " + var.getName() + " = " + var.toString()); } } else if (trace) { trace(ctx, "Variable not found: " + ctx.L_ID(i).getText()); } } exec.incRowCount(); exec.setSqlSuccess(); } else { exec.setSqlCode(100); exec.signal(Signal.Type.NOTFOUND); } } } catch (SQLException e) { exec.setSqlCode(e); exec.signal(Signal.Type.SQLEXCEPTION, e.getMessage(), e); } return 0; }
/** Assignment from SELECT statement */ public Integer assignFromSelect(HplsqlParser.Assignment_stmt_select_itemContext ctx) { String sql = evalPop(ctx.select_stmt()).toString(); if (trace) { trace(ctx, sql.toString()); } String conn = exec.getStatementConnection(); Query query = exec.executeQuery(ctx, sql.toString(), conn); if (query.error()) { exec.signal(query); return 1; } exec.setSqlSuccess(); try { ResultSet rs = query.getResultSet(); ResultSetMetaData rm = null; if (rs != null) { rm = rs.getMetaData(); int cnt = ctx.ident().size(); if (rs.next()) { for (int i = 1; i <= cnt; i++) { Var var = exec.findVariable(ctx.ident(i - 1).getText()); if (var != null) { var.setValue(rs, rm, i); if (trace) { trace(ctx, "COLUMN: " + rm.getColumnName(i) + ", " + rm.getColumnTypeName(i)); trace(ctx, "SET " + var.getName() + " = " + var.toString()); } } else if (trace) { trace(ctx, "Variable not found: " + ctx.ident(i - 1).getText()); } } exec.incRowCount(); exec.setSqlSuccess(); } else { exec.setSqlCode(100); exec.signal(Signal.Type.NOTFOUND); } } } catch (SQLException e) { exec.signal(query); return 1; } finally { exec.closeQuery(query, conn); } return 0; }
/** * Updates the internal reference map based on the provided parameters. If {@code scriptRoot} is * not SCRIPT, it basically replaces the internal map with the new one, otherwise it replaces all * the information associated to the given script. * * @param refMapPatch The reference map result of a {@link ReferenceCollectingCallback} pass which * might be collected from the whole AST or just a sub-tree associated to a SCRIPT node. * @param root AST sub-tree root on which reference collection was done. */ void updateGlobalVarReferences(Map<Var, ReferenceCollection> refMapPatch, Node root) { if (refMap == null || !root.isScript()) { resetGlobalVarReferences(refMapPatch); return; } InputId inputId = root.getInputId(); Preconditions.checkNotNull(inputId); // Note there are two assumptions here (i) the order of compiler inputs // has not changed and (ii) all references are in the order they appear // in AST (this is enforced in ReferenceCollectionCallback). removeScriptReferences(inputId); for (Entry<Var, ReferenceCollection> entry : refMapPatch.entrySet()) { Var var = entry.getKey(); if (var.isGlobal()) { replaceReferences(var.getName(), inputId, entry.getValue()); } } }
private String getVariableAlias(Var var) { return parent.getVariables().get(var.getName()).getAlias(); }
@Override public void meet(Var node) throws RuntimeException { // distinguish between the case where the variable is plain and the variable is bound SQLVariable sv = parent.getVariables().get(node.getName()); if (sv == null) { builder.append("NULL"); } else if (sv.getBindings().size() > 0) { // in case the variable is actually an alias for an expression, we evaluate that expression // instead, effectively replacing the // variable occurrence with its value sv.getBindings().get(0).visit(this); } else { String var = sv.getAlias(); if (sv.getProjectionType() != ValueType.NODE && sv.getProjectionType() != ValueType.NONE) { // in case the variable represents a constructed or bound value instead of a node, we need // to // use the SQL expression as value; SQL should take care of proper casting... // TODO: explicit casting needed? builder.append(sv.getExpressions().get(0)); } else { // in case the variable represents an entry from the NODES table (i.e. has been bound to a // node // in the database, we take the NODES alias and resolve to the correct column according to // the // operator type switch (optypes.peek()) { case STRING: Preconditions.checkState(var != null, "no alias available for variable"); builder.append(var).append(".svalue"); break; case INT: Preconditions.checkState(var != null, "no alias available for variable"); builder.append(var).append(".ivalue"); break; case DECIMAL: case DOUBLE: Preconditions.checkState(var != null, "no alias available for variable"); builder.append(var).append(".dvalue"); break; case BOOL: Preconditions.checkState(var != null, "no alias available for variable"); builder.append(var).append(".bvalue"); break; case DATE: Preconditions.checkState(var != null, "no alias available for variable"); builder.append(var).append(".tvalue"); break; case TZDATE: Preconditions.checkState(var != null, "no alias available for variable"); builder.append(parent.getDialect().getDateTimeTZ(var)); break; case URI: Preconditions.checkState(var != null, "no alias available for variable"); builder.append(var).append(".svalue"); break; case TERM: case NODE: if (sv.getExpressions().size() > 0) { // this allows us to avoid joins with the nodes table for simple expressions that only // need the ID builder.append(sv.getExpressions().get(0)); } else { Preconditions.checkState(var != null, "no alias available for variable"); builder.append(var).append(".id"); } break; } } } }
@Override public void setVar(Var var) { context.put(var.getName(), var); }
/** Executing or building SELECT statement */ public Integer select(HplsqlParser.Select_stmtContext ctx) { if (ctx.parent instanceof HplsqlParser.StmtContext) { exec.stmtConnList.clear(); trace(ctx, "SELECT"); } boolean oldBuildSql = exec.buildSql; exec.buildSql = true; StringBuilder sql = new StringBuilder(); if (ctx.cte_select_stmt() != null) { sql.append(evalPop(ctx.cte_select_stmt()).toString()); sql.append("\n"); } sql.append(evalPop(ctx.fullselect_stmt()).toString()); exec.buildSql = oldBuildSql; if (!(ctx.parent instanceof HplsqlParser.StmtContext)) { // No need to execute at this stage exec.stackPush(sql); return 0; } if (trace && ctx.parent instanceof HplsqlParser.StmtContext) { trace(ctx, sql.toString()); } if (exec.getOffline()) { trace(ctx, "Not executed - offline mode set"); return 0; } String conn = exec.getStatementConnection(); Query query = exec.executeQuery(ctx, sql.toString(), conn); if (query.error()) { exec.signal(query); return 1; } trace(ctx, "SELECT completed successfully"); exec.setSqlSuccess(); try { ResultSet rs = query.getResultSet(); ResultSetMetaData rm = null; if (rs != null) { rm = rs.getMetaData(); } int into_cnt = getIntoCount(ctx); if (into_cnt > 0) { trace(ctx, "SELECT INTO statement executed"); if (rs.next()) { for (int i = 1; i <= into_cnt; i++) { String into_name = getIntoVariable(ctx, i - 1); Var var = exec.findVariable(into_name); if (var != null) { var.setValue(rs, rm, i); if (trace) { trace(ctx, "COLUMN: " + rm.getColumnName(i) + ", " + rm.getColumnTypeName(i)); trace(ctx, "SET " + var.getName() + " = " + var.toString()); } } else { trace(ctx, "Variable not found: " + into_name); } } exec.incRowCount(); exec.setSqlSuccess(); } else { exec.setSqlCode(100); exec.signal(Signal.Type.NOTFOUND); } } // Print all results for standalone SELECT statement else if (ctx.parent instanceof HplsqlParser.StmtContext) { int cols = rm.getColumnCount(); if (trace) { trace(ctx, "Standalone SELECT executed: " + cols + " columns in the result set"); } while (rs.next()) { for (int i = 1; i <= cols; i++) { if (i > 1) { System.out.print("\t"); } System.out.print(rs.getString(i)); } System.out.println(""); exec.incRowCount(); } } // Scalar subquery else { trace(ctx, "Scalar subquery executed, first row and first column fetched only"); if (rs.next()) { exec.stackPush(new Var().setValue(rs, rm, 1)); exec.setSqlSuccess(); } else { evalNull(); exec.setSqlCode(100); } } } catch (SQLException e) { exec.signal(query); exec.closeQuery(query, exec.conf.defaultConnection); return 1; } exec.closeQuery(query, exec.conf.defaultConnection); return 0; }