tree edit_typeset_rep::exec (tree t, hashmap<string,tree> H, bool expand_refs) { hashmap<string,tree> H2; env->read_env (H2); env->write_env (H); t= env->exec (t); if (expand_refs) t= expand_references (t, buf->data->ref); t= simplify_execed (t); t= simplify_correct (t); env->write_env (H2); return t; }
static tree expand_references (tree t, hashmap<string,tree> h) { if (is_atomic (t)) return t; if (is_func (t, REFERENCE, 1) || is_func (t, PAGEREF)) { string ref= as_string (simplify_execed (t[0])); if (h->contains (ref)) { int which= is_func (t, REFERENCE, 1)? 0: 1; return tree (HLINK, copy (h[ref][which]), "#" * ref); } return tree (HLINK, "?", "#" * ref); } int i, n= N(t); tree r (t, n); for (i=0; i<n; i++) r[i]= expand_references (t[i], h); return r; }
void CMP_compile_request( gpre_req* request) { // if there isn't a request handle specified, make one! if (!request->req_handle && (request->req_type != REQ_procedure)) { request->req_handle = (TEXT*) MSC_alloc(20); sprintf(request->req_handle, gpreGlob.ident_pattern, CMP_next_ident()); } if (!request->req_trans) request->req_trans = gpreGlob.transaction_name; if (!request->req_request_level) request->req_request_level = "0"; request->req_ident = CMP_next_ident(); // If this is an SQL blob cursor, compile the blob and get out fast. if (request->req_flags & (REQ_sql_blob_open | REQ_sql_blob_create)) { for (blb* blob = request->req_blobs; blob; blob = blob->blb_next) cmp_blob(blob, true); return; } // Before we get too far, make sure an eof field has been // constructed. If not, do so now. ref* reference; if (!eof_field) { eof_field = MET_make_field(gpreGlob.utility_name, dtype_short, sizeof(SSHORT), false); count_field = MET_make_field(gpreGlob.count_name, dtype_long, sizeof(SLONG), false); slack_byte_field = MET_make_field(gpreGlob.slack_name, dtype_text, 1, false); reference = (ref*) MSC_alloc(REF_LEN); reference->ref_value = "0"; lit0 = MSC_unary(nod_literal, (gpre_nod*) reference); reference = (ref*) MSC_alloc(REF_LEN); reference->ref_value = "1"; lit1 = MSC_unary(nod_literal, (gpre_nod*) reference); } // Handle different request types differently switch (request->req_type) { case REQ_create_database: case REQ_ddl: CMD_compile_ddl(request); return; case REQ_slice: cmp_slice(request); return; case REQ_ready: cmp_ready(request); return; case REQ_procedure: cmp_procedure(request); return; } // expand any incomplete references or values expand_references(request->req_references); expand_references(request->req_values); // Initialize the blr string request->req_blr = request->req_base = MSC_alloc(500); request->req_length = 500; if (request->req_flags & REQ_blr_version4) request->add_byte(blr_version4); else request->add_byte(blr_version5); // If there are values to be transmitted, make a port // to hold them if (request->req_values) request->req_vport = make_port(request, request->req_values); // If this is a FOR type request, an eof field reference needs // to be generated. Do it. switch (request->req_type) { case REQ_for: case REQ_cursor: case REQ_any: reference = (ref*) MSC_alloc(REF_LEN); reference->ref_field = eof_field; reference->ref_next = request->req_references; break; case REQ_mass_update: reference = (ref*) MSC_alloc(REF_LEN); reference->ref_field = count_field; reference->ref_next = request->req_references; break; default: reference = request->req_references; } // Assume that a general port needs to be constructed. gpre_port* port; if ((request->req_type != REQ_insert) && (request->req_type != REQ_store2) && (request->req_type != REQ_set_generator)) { request->req_primary = port = make_port(request, reference); } // Loop thru actions looking for something interesting to do. Not // all action types are "interesting", so don't worry about missing // ones. upd* update; for (act* action = request->req_actions; action; action = action->act_next) { switch (action->act_type) { case ACT_modify: case ACT_erase: case ACT_update: update = (upd*) action->act_object; expand_references(update->upd_references); update->upd_port = make_port(request, update->upd_references); if (!request->req_sync) request->req_sync = make_port(request, 0); break; case ACT_store: if (request->req_type == REQ_store2) { request->req_primary = make_port(request, action->act_object); update_references(request->req_primary->por_references); } break; case ACT_store2: update = (upd*) action->act_object; expand_references(update->upd_references); update->upd_port = make_port(request, update->upd_references); update_references(update->upd_port->por_references); break; case ACT_select: case ACT_fetch: cmp_fetch(action); break; } } cmp_blr(request); request->add_byte(blr_eoc); // Compute out final blr lengths request->req_length = request->req_blr - request->req_base; request->req_blr = request->req_base; // Finally, assign identifiers to any blobs that may have been referenced for (blb* blob = request->req_blobs; blob; blob = blob->blb_next) cmp_blob(blob, false); }