示例#1
0
//---------------------------------------------------------------
// START FUNC DECL
int
f1opf2(
    char *tbl,
    char *f1,
    char *str_op_spec,
    char *f2
)
// STOP FUNC DECL
{
    int status = 0;
    char *f1_X = NULL;
    size_t f1_nX = 0;
    char *nn_f1_X = NULL;
    size_t nn_f1_nX = 0;
    char *sz_f1_X = NULL;
    size_t sz_f1_nX = 0;
    FLD_TYPE *f1_meta = NULL, *nn_f1_meta = NULL, *sz_f1_meta = NULL;
    long long nR;
    int tbl_id = INT_MIN, f1_id = INT_MIN, nn_f1_id = INT_MIN, sz_f1_id = INT_MIN;
    int         f2_id = INT_MIN, nn_f2_id = INT_MIN, sz_f2_id = INT_MIN;
    char str_meta_data[1024];
    int f1type;
    char *op = NULL, *str_val = NULL;
    FILE *ofp = NULL;
    char *opfile = NULL;
    FILE *nn_ofp = NULL;
    char *nn_opfile = NULL;
    FILE *sz_ofp = NULL;
    char *sz_opfile = NULL;
    char *xform_enum = NULL, *hash_algo = NULL;
    //----------------------------------------------------------------
    if ( ( tbl == NULL ) || ( *tbl == '\0' ) ) {
        go_BYE(-1);
    }
    if ( ( f1 == NULL ) || ( *f1 == '\0' ) ) {
        go_BYE(-1);
    }
    if ( ( f2 == NULL ) || ( *f2 == '\0' ) ) {
        go_BYE(-1);
    }
    if ( ( str_op_spec == NULL ) || ( *str_op_spec == '\0' ) ) {
        go_BYE(-1);
    }
    zero_string(str_meta_data, 1024);
    //--------------------------------------------------------
    status = extract_name_value(str_op_spec, "op=", ":", &op);
    cBYE(status);
    if ( op == NULL ) {
        go_BYE(-1);
    }
    //--------------------------------------------------------
    status = chk_if_ephemeral(&f2);
    cBYE(status);
    status = is_tbl(tbl, &tbl_id);
    cBYE(status);
    chk_range(tbl_id, 0, g_n_tbl);
    nR = g_tbl[tbl_id].nR;
    status = is_fld(NULL, tbl_id, f1, &f1_id);
    cBYE(status);
    chk_range(f1_id, 0, g_n_fld);
    f1_meta = &(g_fld[f1_id]);
    status = rs_mmap(f1_meta->filename, &f1_X, &f1_nX, 0);
    cBYE(status);
    // Get nn field for f1 if if it exists
    nn_f1_id = g_fld[f1_id].nn_fld_id;
    if ( nn_f1_id >= 0 ) {
        nn_f1_meta = &(g_fld[nn_f1_id]);
        status = rs_mmap(nn_f1_meta->filename, &nn_f1_X, &nn_f1_nX, 0);
        cBYE(status);
    }
    //---------------------------------------------
    status = mk_ifldtype(f1_meta->fldtype, &f1type);
    /* TODO: Why do we get an error for 'char string' ? */
    // If f1 type is 'char string', then get sz field
    if ( strcmp(f1_meta->fldtype, "char string") == 0 ) {
        sz_f1_id = g_fld[f1_id].sz_fld_id;
        chk_range(sz_f1_id, 0, g_n_fld);
        sz_f1_meta = &(g_fld[sz_f1_id]);
        status = rs_mmap(sz_f1_meta->filename, &sz_f1_X, &sz_f1_nX, 0);
        cBYE(status);
    }
    //--------------------------------------------------------
    if ( strcmp(op, "xform") == 0 ) {
        bool is_some_null;
        status = open_temp_file(&ofp, &opfile, 0);
        cBYE(status);
        status = open_temp_file(&nn_ofp, &nn_opfile, 0);
        cBYE(status);
        status = open_temp_file(&sz_ofp, &sz_opfile, 0);
        cBYE(status);
        status = str_xform(nR, f1_X, (int *)sz_f1_X, nn_f1_X, str_op_spec,
                           ofp, nn_ofp, sz_ofp, &is_some_null);
        cBYE(status);
        fclose_if_non_null(ofp);
        fclose_if_non_null(nn_ofp);
        fclose_if_non_null(sz_ofp);
        sprintf(str_meta_data, "filename=%s:fldtype=char string:n_sizeof=0",
                opfile);
        status = add_fld(tbl, f2, str_meta_data, &f2_id);
        cBYE(status);
        status = add_aux_fld(tbl, f2, sz_opfile, "sz", &sz_f2_id);
        cBYE(status);
        if ( is_some_null ) {
            status = add_aux_fld(tbl, f2, nn_opfile, "nn", &nn_f2_id);
            cBYE(status);
        }
        else {
            unlink(nn_opfile);
        }
    }
    else if ( strcmp(op, "hash") == 0 ) {
        int hash_len;
        char *endptr = NULL;

        status = extract_name_value(str_op_spec, "len=", ":", &str_val);
        cBYE(status);
        if  ( str_val == NULL ) {
            go_BYE(-1);
        }
        hash_len = strtol(str_val, &endptr, 10);
        if ( *endptr != '\0' ) {
            go_BYE(-1);
        }

        status = extract_name_value(str_op_spec, "hash_algo=", ":", &hash_algo);
        cBYE(status);

        status = open_temp_file(&ofp, &opfile, 0);
        cBYE(status);
        status = f1opf2_hash(hash_algo, nR, f1_X, f1_nX, (int *)sz_f1_X,
                             f1_meta->n_sizeof, nn_f1_X, hash_len, ofp);
        cBYE(status);
        fclose_if_non_null(ofp);
        sprintf(str_meta_data, "filename=%s", opfile);
        switch ( hash_len ) {
        case 4 :
            strcat(str_meta_data, ":fldtype=int:n_sizeof=4");
            break;
        case 8 :
            strcat(str_meta_data, ":fldtype=long long:n_sizeof=8");
            break;
        default :
            go_BYE(-1);
            break;
        }
        fclose_if_non_null(ofp);
        status = add_fld(tbl, f2, str_meta_data, &f2_id);
        cBYE(status);
    }
    else if ( ( strcmp(op, "conv") == 0 ) ||
              ( strcmp(op, "dateconv" ) == 0 ) ||
              ( strcmp(op, "bitcount" ) == 0 ) ||
              ( strcmp(op, "sqrt" ) == 0 ) ||
              ( strcmp(op, "!" ) == 0 ) ||
              ( strcmp(op, "++" ) == 0 ) ||
              ( strcmp(op, "--" ) == 0 ) ||
              ( strcmp(op, "~" ) == 0 )
            ) {
        status = vec_f1opf2(nR, f1type, str_meta_data,
                            f1_X, nn_f1_X, sz_f1_X, op, str_op_spec, &opfile, &nn_opfile);
        cBYE(status);
        status = add_fld(tbl, f2, str_meta_data, &f2_id);
        cBYE(status);
        if ( nn_opfile != NULL ) {
            status = add_aux_fld(tbl, f2, nn_opfile, "nn", &nn_f2_id);
            cBYE(status);
        }
    }
    else if ( strcmp(op, "shift") == 0 ) {
        int ival;
        char *endptr = NULL;
        status = extract_name_value(str_op_spec, "val=", ":", &str_val);
        cBYE(status);
        ival = strtol(str_val, &endptr, 10);
        if ( *endptr != '\0' ) {
            fprintf(stderr, "invalid shift specifier = [%s] \n", str_val);
            go_BYE(-1);
        }
        if ( ( ival == 0 ) || ( ival > MAX_SHIFT ) ||
                (  ival < -MAX_SHIFT ) || (ival >= nR )) {
            fprintf(stderr, "shift = [%d] is out of bounds \n", ival);
            go_BYE(-1);
        }

        status = open_temp_file(&ofp, &opfile, 0);
        cBYE(status);
        status = open_temp_file(&nn_ofp, &nn_opfile, 0);
        cBYE(status);
        status = f1opf2_shift(f1_X, nn_f1_X, nR, f1_meta->fldtype, ival,
                              ofp, nn_ofp);
        cBYE(status);
        fclose_if_non_null(ofp);
        fclose_if_non_null(nn_ofp);
        sprintf(str_meta_data, "filename=%s:fldtype=%s:n_sizeof=%d",opfile,
                f1_meta->fldtype, f1_meta->n_sizeof);
        status = add_fld(tbl, f2, str_meta_data, &f2_id);
        cBYE(status);
        status = add_aux_fld(tbl, f2, nn_opfile, "nn", &nn_f2_id);
        cBYE(status);
    }
    else if ( strcmp(op, "cum") == 0 ) {
        /* TODO: Document. If you do a cum, resultant field is all def */
        char *new_fld_type = NULL;
        int optype, n_sizeof;
        char *str_reset_on = NULL, *str_reset_to = NULL, *endptr = NULL;
        long long reset_on = 0, reset_to = 0;
        bool is_reset = false;
        status = extract_name_value(str_op_spec, "newtype=", ":", &new_fld_type);
        cBYE(status);
        status = extract_name_value(str_op_spec, "reset_on=", ":",
                                    &str_reset_on);
        cBYE(status);
        if ( str_reset_on != NULL ) {
            reset_on = strtoll(str_reset_on, &endptr, 10);
            if ( *endptr != '\0' ) {
                go_BYE(-1);
            }
            is_reset = true;
            status = extract_name_value(str_op_spec, "reset_to=", ":",
                                        &str_reset_to);
            cBYE(status);
            if ( str_reset_to == NULL ) {
                go_BYE(-1);
            }
            reset_to = strtoll(str_reset_to, &endptr, 10);
            if ( *endptr != '\0' ) {
                go_BYE(-1);
            }
        }
        if ( new_fld_type == NULL ) {
            optype = f1type;
            new_fld_type = strdup(f1_meta->fldtype);
            n_sizeof = f1_meta->n_sizeof;
        }
        else {
            if ( strcmp(new_fld_type, "int") == 0 ) {
                optype = FLDTYPE_INT;
                n_sizeof = sizeof(int);
            }
            else if ( strcmp(new_fld_type, "long long") == 0 ) {
                optype = FLDTYPE_LONGLONG;
                n_sizeof = sizeof(long long);
            }
            else {
                go_BYE(-1);
            }
        }
        status = f1opf2_cum(f1_X, nR, f1type, optype, is_reset,
                            reset_on, reset_to, &opfile);
        cBYE(status);
        sprintf(str_meta_data, "filename=%s:fldtype=%s:n_sizeof=%d",opfile,
                new_fld_type, n_sizeof);
        status = add_fld(tbl, f2, str_meta_data, &f2_id);
        cBYE(status);
        free_if_non_null(new_fld_type);
        free_if_non_null(str_reset_on);
        free_if_non_null(str_reset_to);
    }
    else {
        fprintf(stderr, "Invalid op = [%s] \n", op);
        go_BYE(-1);
    }
BYE:
    fclose_if_non_null(ofp);
    fclose_if_non_null(nn_ofp);
    g_write_to_temp_dir = false;
    rs_munmap(f1_X, f1_nX);
    rs_munmap(nn_f1_X, nn_f1_nX);
    rs_munmap(sz_f1_X, sz_f1_nX);
    free_if_non_null(op);
    free_if_non_null(xform_enum);
    free_if_non_null(hash_algo);
    free_if_non_null(str_val);
    free_if_non_null(opfile);
    free_if_non_null(nn_opfile);
    free_if_non_null(sz_opfile);
    return(status);
}
示例#2
0
文件: compound.c 项目: TimLand/datacl
// START FUNC DECL
int
exec_comp_expr(
	       int tbl_id,
	       TBL_REC_TYPE tbl_rec,
	       COMP_EXPR_TYPE *comp_expr, 
	       int n_comp_expr
	       )
// STOP FUNC DECL
{
  int status = 0;
  // Following used to combine f_to_s and f1f2_to_s 
  double l_partsum_0_F8; long long l_partsum_0_I8, l_partsum_1_I8;
  double     partsum_0_F8[MAX_STATEMENTS_IN_COMP_EXPR];
  long long  partsum_0_I8[MAX_STATEMENTS_IN_COMP_EXPR];
  long long  partsum_1_I8[MAX_STATEMENTS_IN_COMP_EXPR];
  long long  partsum_2_I8[MAX_STATEMENTS_IN_COMP_EXPR];
  bool  is_numer_set[MAX_STATEMENTS_IN_COMP_EXPR];
#define BUFLEN 32
#define RSLT_BUF_SIZE 1024
  char op[BUFLEN]; bool is_null;
  char rslt_buf[RSLT_BUF_SIZE];
  char buf0[RSLT_BUF_SIZE];
  char buf1[RSLT_BUF_SIZE];
  char buf2[RSLT_BUF_SIZE];
  zero_string(rslt_buf, RSLT_BUF_SIZE);
  zero_string(buf0, RSLT_BUF_SIZE);
  zero_string(buf1, RSLT_BUF_SIZE);
  zero_string(buf2, RSLT_BUF_SIZE);
  long long time_per_expr[MAX_STATEMENTS_IN_COMP_EXPR];
  long long t_before, t_after;

  for ( int i = 0; i < MAX_STATEMENTS_IN_COMP_EXPR; i++ ) { 
    time_per_expr[i] = 0;
  }

  if ( n_comp_expr <= 1 ) { go_BYE(-1); }
  for ( int i = 0; i < MAX_STATEMENTS_IN_COMP_EXPR; i++ ) { 
    // numerator assigned inside loop
    partsum_0_I8[i] = 0;
    partsum_0_F8[i] = 0;
    partsum_1_I8[i] = 0;
    partsum_2_I8[i] = 0;
    is_numer_set[i] = false;
  }

  // determine number of blocks and block size. Last block may be bigger.
  int block_size = COMP_EXPR_BLOCK_SIZE;
  // block_size = 5; // TODO P0 Just for debugging
  if ( n_comp_expr <= 1 ) { go_BYE(-1); }
  long long nR = tbl_rec.nR;
  int num_blocks = nR / block_size;
  if ( num_blocks == 0 ) { num_blocks = 1; }
  for ( int b = 0; b < num_blocks; b++ ) {
    long long lb = block_size * b;
    long long ub = lb + block_size;
    if ( b == ( num_blocks-1) ) { ub = nR; }
    long long eff_nR = ub - lb;
    for ( int i = 0; i < n_comp_expr; i++ ) { 
      t_before = get_time_usec();
      long long *cntI8 = NULL; long long dst_nR; 
      char *f1_X = NULL, *nn_f1_X = NULL; long long f1nR = 0; FLD_TYPE f1type;
      char *f2_X = NULL, *nn_f2_X = NULL; long long f2nR = 0; FLD_TYPE f2type;
      char *f3_X = NULL, *nn_f3_X = NULL; long long f3nR = 0; FLD_TYPE f3type;
      char *f4_X = NULL, *nn_f4_X = NULL; long long f4nR = 0; FLD_TYPE f4type;
      int *src_fld = NULL;
      zero_string(op, BUFLEN);
      char *str_op_spec = comp_expr[i].op_spec;
      char *str_scalar  = comp_expr[i].scalar;
      // NOTE ASSUMPTION THAT nn is stored as I1 and not as B
      status = offset_pointers(tbl_id, comp_expr, i, 0, lb, &f1nR, &f1type, 
	  &f1_X, &nn_f1_X); 
      cBYE(status);
      status = offset_pointers(tbl_id, comp_expr, i, 1, lb, &f2nR, &f2type, 
	  &f2_X, &nn_f2_X); 
      cBYE(status);
      status = offset_pointers(tbl_id, comp_expr, i, 2, lb, &f3nR, &f3type, 
	  &f3_X, &nn_f3_X); 
      cBYE(status);
      status = offset_pointers(tbl_id, comp_expr, i, 3, lb, &f4nR, &f4type, 
	  &f4_X, &nn_f4_X); 
      cBYE(status);

      /* START: Some additional checking on pointers */
      switch ( comp_expr[i].op ) { 
      case op_count    : 
      case op_countf   : 
      case op_f1f2opf3 : 
      case op_f1opf2f3 : 
	break; 
      default : 
	/* there is no f3 field for these operations */
	if ( f3_X    != NULL ) { go_BYE(-1); }
	if ( nn_f3_X != NULL ) { go_BYE(-1); }
	if ( f3type != undef_fldtype ) { go_BYE(-1); }
	break;
      }

      switch ( comp_expr[i].op ) { 
      case op_countf : 
	break; 
      default : 
	/* there is no f4 field for these operations */
	if ( f4_X    != NULL ) { go_BYE(-1); }
	if ( nn_f4_X != NULL ) { go_BYE(-1); }
	if ( f4type != undef_fldtype ) { go_BYE(-1); }
	break;
      }
      /* STOP: Some additional checking on pointers */


      int nT = 1;
      switch ( comp_expr[i].op ) { 
      case op_f1s1opf2 : 
	status = vec_f1s1opf2(eff_nR, f1type, f1_X, nn_f1_X, 
			      str_scalar, str_op_spec, f2_X, nn_f2_X, f2type);
	break;
      case op_f1opf2f3 : 
	go_BYE(-1); // TODO: P2 To be implemented
	break;
      case op_f1f2opf3 : 
	status = vec_f1f2opf3(eff_nR, f1type, f2type, f1_X, nn_f1_X, 
			      f2_X, nn_f2_X, str_op_spec, f3type, f3_X, nn_f3_X);
	break;
      case op_f1opf2 : 
	status = extract_S(str_op_spec, "op=[", "]", op, BUFLEN, &is_null);
	cBYE(status);
	if ( is_null ) { go_BYE(-1); }
	status = vec_f1opf2(eff_nR, f1type, f1_X, nn_f1_X, op,
			    f2_X, nn_f2_X, f2type);

	break;
      case op_countf : 
	// fld1 is src fld 
	// fld2 is fk to outtbl
	// fld3 is cfld
	// fld4 is cnt in outtbl
	src_fld = (int *)f1_X;
	cntI8 = (long long *)f4_X;
	dst_nR = f4nR;
	if ( b == 0 ) { 
	  assign_const_I8(cntI8, dst_nR, 0);
	}
	if ( f3_X != NULL ) {
	  switch ( f2type ) { 
	  case I1 : 
            status = compute_nT_for_count(eff_nR, dst_nR, &nT); cBYE(status);
	    if ( nT == 1 ) { 
	      status = countf_nn_I1(src_fld, (char *)f1_X, eff_nR, 
		  f3_X, cntI8, dst_nR, false);  cBYE(status);
	    }
	    else {
	      status = par_countf_cfld_I1(src_fld, (char *)f2_X, eff_nR, 
		  f3_X, cntI8, dst_nR, nT);  cBYE(status);
	    }
	    break;
	  case I2 : 
	    if ( nT == 1 ) { 
	      status = countf_nn_I2(src_fld, (short *)f2_X, eff_nR, 
		  f3_X, cntI8, dst_nR, false); cBYE(status);
	    }
	    else {
	      status = par_countf_cfld_I2(src_fld, (short *)f2_X, eff_nR, 
		  f3_X, cntI8, dst_nR, nT);  cBYE(status);
	    }
	    break;
	  case I4 : 
	    status = countf_nn_I4(src_fld, (int *)f2_X,  eff_nR, f3_X, 
		cntI8, dst_nR, false); 
	    break;
	  case I8 : 
	    status = countf_nn_I8(src_fld, (long long *)f2_X, eff_nR, 
		f3_X, cntI8, dst_nR, false); 
	    break;
	  default : 
	    go_BYE(-1);
	    break;
	  }
	}
	else {
	  switch ( f2type ) { 
	  case I1 : 
	    if ( nT == 1 ) { 
	      status = countf_I1(src_fld, (char *)f2_X, eff_nR, 
		  cntI8, dst_nR, false); 
	    }
	    else {
	      status = par_countf_I1(src_fld, (char *)f2_X, eff_nR, 
		  cntI8, dst_nR, nT);  cBYE(status);
	    }
	    break;
	  case I2 : 
	    status = countf_I2(src_fld, (short *)f2_X, eff_nR, cntI8, 
		dst_nR, false); 
	    break;
	  case I4 : 
	    status = countf_I4(src_fld, (int *)f2_X, eff_nR, cntI8, 
		dst_nR, false); 
	    break;
	  case I8 : 
	    status = countf_I8(src_fld, (long long *)f2_X, eff_nR, 
		cntI8, dst_nR, false); 
	    break;
	  default : 
	    go_BYE(-1);
	    break;
	  }
	}
	cBYE(status);
	break;
      case op_count : 
	// fld1 is fk to outtbl
	// fld2 is cfld
	// fld3 is cnt in outtbl
	cntI8 = (long long *)f3_X;
	dst_nR = f3nR;
	if ( b == 0 ) { 
	  assign_const_I8(cntI8, dst_nR, 0);
	}
	if ( f2_X != NULL ) {
	  switch ( f1type ) { 
	  case I1 : 
            status = compute_nT_for_count(eff_nR, dst_nR, &nT); cBYE(status);
	    if ( nT == 1 ) { 
	      status = count_nn_I1((char *)f1_X, eff_nR, f2_X, cntI8, 
				   dst_nR, false);  cBYE(status);
	    }
	    else {
	      status = par_count_cfld_I1((char *)f1_X, eff_nR, f2_X, cntI8, 
					 dst_nR, nT);  cBYE(status);
	    }
	    break;
	  case I2 : 
	    if ( nT == 1 ) { 
	      status = count_nn_I2((short *)f1_X, eff_nR, f2_X, cntI8, 
				   dst_nR, false); cBYE(status);
	    }
	    else {
	      status = par_count_cfld_I2((short *)f1_X, eff_nR, f2_X, cntI8, 
					 dst_nR, nT);  cBYE(status);
	    }
	    break;
	  case I4 : 
	    status = count_nn_I4((int *)f1_X,       eff_nR, f2_X, cntI8, dst_nR, false); 
	    break;
	  case I8 : 
	    status = count_nn_I8((long long *)f1_X, eff_nR, f2_X, cntI8, dst_nR, false); 
	    break;
	  default : 
	    go_BYE(-1);
	    break;
	  }
	}
	else {
	  switch ( f1type ) { 
	  case I1 : 
	    if ( nT == 1 ) { 
	      status = count_I1((char *)f1_X, eff_nR, cntI8, dst_nR, false); 
	    }
	    else {
	      status = par_count_I1((char *)f1_X, eff_nR, cntI8, 
				    dst_nR, nT);  cBYE(status);
	    }
	    break;
	  case I2 : 
	    status = count_I2((short *)f1_X, eff_nR, cntI8, dst_nR, false); 
	    break;
	  case I4 : 
	    status = count_I4((int *)f1_X, eff_nR, cntI8, dst_nR, false); 
	    break;
	  case I8 : 
	    status = count_I8((long long *)f1_X, eff_nR, cntI8, dst_nR, false); 
	    break;
	  default : 
	    go_BYE(-1);
	    break;
	  }
	}
	cBYE(status);
	break;
      case op_f_to_s : 
	status = vec_f_to_s(f1_X, f1type, nn_f1_X, eff_nR, 
			    str_op_spec, rslt_buf, RSLT_BUF_SIZE);
	// Combine buffers across invocations
	status = read_nth_val(rslt_buf, ":", 0, buf0, RSLT_BUF_SIZE);
	cBYE(status);
	status = read_nth_val(rslt_buf, ":", 1, buf1, RSLT_BUF_SIZE);
	cBYE(status);
	status = stoI8(buf1, &l_partsum_1_I8); cBYE(status); 
	if ( l_partsum_1_I8 < 0 ) { go_BYE(-1); }
	if ( l_partsum_1_I8 > 0 ) {
	  partsum_1_I8[i] += l_partsum_1_I8;

	  switch ( f1type ) {
	  case I1 : case I2 : case I4 : case I8 : 
	    status = stoI8(buf0, &l_partsum_0_I8); cBYE(status); 
	    if ( is_numer_set[i] == false ) {
	      is_numer_set[i] = true; 
	      partsum_0_I8[i] = l_partsum_0_I8;
	    }
	    else {
	      if ( strcmp(str_op_spec, "min") == 0 ) { 
		partsum_0_I8[i] = min(partsum_0_I8[i], l_partsum_0_I8);
	      }
	      else if ( strcmp(str_op_spec, "max") == 0 ) { 
		partsum_0_I8[i] = max(partsum_0_I8[i], l_partsum_0_I8);
	      }
	      else if ( strcmp(str_op_spec, "sum") == 0 ) { 
		partsum_0_I8[i] += l_partsum_0_I8;
	      }
	      else {
		go_BYE(-1);
	      }
	    }
	    break;
	  case F4 : case F8 : 
	    status = stoF8(buf0, &l_partsum_0_F8); cBYE(status); 
	    if ( is_numer_set[i] == false ) {
	      is_numer_set[i] = true; 
	      partsum_0_F8[i] = l_partsum_0_F8;
	    }
	    else {
	      if ( strcmp(str_op_spec, "min") == 0 ) { 
		partsum_0_F8[i] = min(partsum_0_F8[i], l_partsum_0_F8);
	      }
	      else if ( strcmp(str_op_spec, "max") == 0 ) { 
		partsum_0_F8[i] = max(partsum_0_F8[i], l_partsum_0_F8);
	      }
	      else if ( strcmp(str_op_spec, "sum") == 0 ) { 
		partsum_0_F8[i] += l_partsum_0_F8;
	      }
	      else {
		go_BYE(-1);
	      }
	    }
	    break;
	  default : 
	    go_BYE(-1);
	    break;
	  }
	}
	break;
      case op_f1f2_to_s : 
	status = core_f1f2_to_s(str_op_spec, f1_X, f1type, f2_X, f2type, 
	    eff_nR, rslt_buf, RSLT_BUF_SIZE);
	cBYE(status);
	// Combine buffers across invocations
	status = read_nth_val(rslt_buf, ":", 0, buf0, RSLT_BUF_SIZE);
	cBYE(status);
	status = read_nth_val(rslt_buf, ":", 1, buf1, RSLT_BUF_SIZE);
	cBYE(status);
	status = read_nth_val(rslt_buf, ":", 2, buf2, RSLT_BUF_SIZE);
	cBYE(status);
	// Note that processing for f1f2_to_s is much simpler than
	// f_to_s because we support much fewer options
	//------------------------------
	long long tempI8;
	status = stoI8(buf0, &tempI8); cBYE(status);
	partsum_0_I8[i] += tempI8; 
	//------------------------------
	status = stoI8(buf1, &tempI8); cBYE(status);
	if ( tempI8 < 0 ) { go_BYE(-1); }
	partsum_1_I8[i] += tempI8; 
	//------------------------------
	status = stoI8(buf2, &tempI8); cBYE(status);
	if ( tempI8 <= 0 ) { go_BYE(-1); }
	partsum_2_I8[i] += tempI8; 
	//------------------------------
      break;
      default : 
	go_BYE(-1);
	break;
      }
      t_after = get_time_usec();
      time_per_expr[i] += (t_after - t_before);
    }
  }
  // Print out scalar variables if any
  for ( int i = 0; i < n_comp_expr; i++ ) { 
    // DBG fprintf(stderr, "time[%d] = %lld \n", i, time_per_expr[i]);
    switch ( comp_expr[i].op ) { 
    case op_f_to_s  : 
      if ( is_numer_set[i] == true ) {
        FLD_TYPE f1type = comp_expr[i].fld[0].fldtype;
	switch ( f1type ) { 
	case I1 : case I2 : case I4 : case I8 : 
	  fprintf(stdout, "%s=%lld:%lld\n", 
	      comp_expr[i].env_var, partsum_0_I8[i], partsum_1_I8[i]);
	  break;
	case F4 : case F8 : 
	  fprintf(stdout, "%s=%lf:%lld\n", 
	      comp_expr[i].env_var, partsum_0_F8[i], partsum_1_I8[i]);
	  break;
	default : 
	  go_BYE(-1);
	  break;
	}
      }
      else {
	fprintf(stdout, "%s=0:0\n", comp_expr[i].env_var);
      }
      break;
    case op_f1f2_to_s  : 
      fprintf(stdout, "%s=%lld:%lld:%lld\n", comp_expr[i].env_var, 
	    partsum_0_I8[i], partsum_1_I8[i], partsum_2_I8[i]);
    break;
    default : 
      // nothing to do 
      break;
    }
  }
 BYE:
  return status ;
}