id_spreadsheet = par_id;
if (id_column>0) {
__SQL_GET_INTEGER(num_first_column,
"SELECT column_number FROM co_sys_spreadsheet_column WHERE id=%d",
id_column )
__ASSERT( (num_first_column>0) , "column with id=%d not found", id_column)
}
if (id_row>0) {
__SQL_GET_INTEGER(num_first_row,
"SELECT row_number FROM co_sys_spreadsheet_row WHERE id=%d",
id_row )
__ASSERT( (num_first_row>0) , "column with id=%d not found", id_row)
}
if (id_last_column>0) {
__SQL_GET_INTEGER(num_last_column,
"SELECT column_number FROM co_sys_spreadsheet_column WHERE id=%d",
id_last_column )
__ASSERT( (num_last_column>0) , "column with id=%d not found", id_last_column)
}
if (id_last_row>0) {
__SQL_GET_INTEGER(num_last_row,
"SELECT row_number FROM co_sys_spreadsheet_row WHERE id=%d",
id_last_row )
__ASSERT( (num_last_row>0) , "row with id=%d not found", id_last_row)
}
if (num_last_column==0) {
__SQL_GET_INTEGER(num_last_column,
"SELECT max(column_number) FROM co_sys_spreadsheet_column WHERE spreadsheet_id=%d",
id_spreadsheet )
}
if (num_last_row==0) {
__SQL_GET_INTEGER(num_last_row,
"SELECT max(row_number) FROM co_sys_spreadsheet_row WHERE spreadsheet_id=%d",
id_spreadsheet )
}
__CREATE_QUERY( "
DELETE FROM co_sys_expression_deps_r WHERE id_session = %d ;

INSERT INTO co_sys_expression_deps_r
SELECT DISTINCT %d as id_session, COLREF.id as c_id, ROWREF.id as r_id,
1 as n, COLREF.id as seed_c_id, ROWREF.id as seed_r_id
FROM
co_sys_spreadsheet_row AS ROWREF, co_sys_spreadsheet_column AS COLREF
WHERE COLREF.spreadsheet_id=%d AND COLREF.column_number>=%d AND COLREF.column_number<=%d AND
ROWREF.spreadsheet_id=%d AND ROWREF.row_number>=%d AND ROWREF.row_number<=%d
;
", cnx->id_session,
cnx->id_session,
id_spreadsheet, num_first_column, num_last_column,
id_spreadsheet, num_first_row, num_last_row)

__SQL_EXEC

{
int n;
int cell_deps, range_deps;
int loops; /* loops in expression? */

for(n=1; n<20; n++) {
__CREATE_QUERY( "
INSERT INTO co_sys_expression_deps_r
SELECT DISTINCT DEP.id_session as id_session, CELL.id_column as c_id, CELL.id_row as r_id,
DEP.n+1 as n, DEP.seed_c_id as seed_c_id, DEP.seed_r_id as seed_r_id
FROM co_sys_expression_deps_r AS DEP, co_sys_expression_cell AS CELL
WHERE
DEP.id_session = %d AND
DEP.n = %d AND -- used in loop
CELL.id_ref_column = DEP.c_id AND
CELL.id_ref_row = DEP.r_id
;
",
cnx->id_session, n)

__SQL_EXEC
cell_deps = ok; /* atoi(PQcmdTuple(res)); */

__CREATE_QUERY( "
INSERT INTO co_sys_expression_deps_r
SELECT DISTINCT DEP.id_session as id_session, RANGE.id_column as c_id, RANGE.id_row as r_id,
DEP.n+1 as n, DEP.seed_c_id as seed_c_id, DEP.seed_r_id as seed_r_id
FROM co_sys_expression_deps_r AS DEP, co_sys_spreadsheet_row AS ROWSRC, co_sys_spreadsheet_column AS COLSRC,
co_sys_expression_range AS RANGE,
co_sys_spreadsheet_row AS ROWREF1, co_sys_spreadsheet_column AS COLREF1,
co_sys_spreadsheet_row AS ROWREF2, co_sys_spreadsheet_column AS COLREF2
WHERE
DEP.id_session = %d AND
ROWSRC.id=DEP.r_id AND
COLSRC.id=DEP.c_id AND
ROWREF1.id=RANGE.id_ref_row AND
COLREF1.id=RANGE.id_ref_column AND
ROWREF2.id=RANGE.id_ref_row2 AND
COLREF2.id=RANGE.id_ref_column2 AND
ROWSRC.spreadsheet_id = ROWREF1.spreadsheet_id AND -- range within the same spreadsheet as our cell
ROWSRC.row_number >= ROWREF1.row_number AND
ROWSRC.row_number <= ROWREF2.row_number AND
COLSRC.column_number >= COLREF1.column_number AND
COLSRC.column_number <= COLREF2.column_number AND
DEP.n = %d -- used in loop
;
",
cnx->id_session, n)
__SQL_EXEC
range_deps = ok; /* atoi(PQcmdTuple(res)); */

if( (cell_deps==0) && (range_deps==0) ) break;

if((n+1)>=20) {
/* last loop in for... and we are still getting dependent cells? */
cou_error( cnx, "Max dependency depth exceeded");
}

/* check for loops: does cell depends on itself? */
loops = 0;
__SQL_GET_INTEGER( loops, "
SELECT count(*) FROM co_sys_expression_deps_r AS DEP
WHERE
DEP.id_session=%d AND
DEP.n>1 AND
DEP.seed_c_id = DEP.c_id AND DEP.seed_r_id = DEP.r_id
;
",
cnx->id_session)

if (loops>0) {
cou_error( cnx, "Expression Loop occured");
}

} /* loop */
//if (n>=EXPR_MAX_DEP) cou_error( cnx, "Unsupported dependency depth (nesting level too big)");
} /* n was visible */

__CREATE_QUERY( "
SELECT DEP.c_id, DEP.r_id, EXPR.expression_parsed, EXPR.id_spreadsheet
FROM co_sys_expression_deps_r AS DEP, co_sys_expression AS EXPR
WHERE DEP.id_session=%d AND
EXPR.id_column = DEP.c_id AND EXPR.id_row=DEP.r_id
GROUP BY DEP.c_id, DEP.r_id, EXPR.expression_parsed, EXPR.id_spreadsheet
ORDER BY MAX(n)
;
",
cnx->id_session)

__SQL_GET_RESULT

cou_logError(cnx, CO_LOG_DEBUG, "ntuples=%d", cor_GetTupleCount(cnx, corec));
{
int i;
if (cor_GetTupleCount(cnx, corec)>0) for (i=0; i<cor_GetTupleCount(cnx, corec); i++) {
int dep_id_spreadsheet;
int dep_id_column;
int dep_id_row;
const char *expression_result;
const char *expression_script;
const char *source;
const char *context;

cou_logError(cnx, CO_LOG_DEBUG, "%s,%s,%s,%s",
cor_GetValue(cnx, corec,i,0),cor_GetValue(cnx, corec,i,1),cor_GetValue(cnx, corec,i,2),cor_GetValue(cnx, corec,i,3));

dep_id_spreadsheet = atoi(cor_GetValue(cnx, corec,i,3));
dep_id_column = atoi(cor_GetValue(cnx, corec,i,0));
dep_id_row = atoi(cor_GetValue(cnx, corec,i,1));
expression_script = cor_GetValue(cnx, corec,i,2);

context = ap_psprintf(p, "
var context = new Object();\n
context.column_id = %d;\n
context.row_id = %d;\n
context.spreadsheet_id = %d;\n
",
dep_id_column, dep_id_row, dep_id_spreadsheet );

source = ap_psprintf(p, "return %s", ++expression_script); /* skips '=' */

@co_call('"sys"','"js_code"', "evaluate", par_area=>'"sys"', par_class=>'"js_code"', par_id=>-2, prolog=>context, direct_code=>source, direct_libs=>'"expression_runtime"', asp=>0 );
expression_result = (char*)cou_getReturnValue( cnx, CO_STRING, &err );

/*
    expression_result = co_priv_callJS(cnx,
     dep_id_spreadsheet, dep_id_column, dep_id_row,
     "evalExpression", cor_GetValue(cnx, corec,i,2) );
*/
/* set cell value */
@co_call('"sys"', '"spreadsheet_cell"', "setAttribute", par_id => dep_id_spreadsheet, par_area => '"sys"' , par_class => '"spreadsheet_cell"' , column_id => dep_id_column, row_id => dep_id_row, attribute_name => '"value_noeval"' , attribute_value => expression_result );
/*
    cparams.par_id = dep_id_spreadsheet;
    cparams.par_area = "sys";
    cparams.par_class = "spreadsheet_cell";
    cparams.column_id = dep_id_column;
    cparams.row_id = dep_id_row;
    cparams.attribute_name = "value_noeval";
    cparams.attribute_value = expression_result;
    cou_broker( "sys", "spreadsheet_cell", "setAttribute", cnx, &cparams );
*/

if (cnx->putJS) {
snprintf(JSOutBuf, JSBUFSIZE, "w_c_by_id(%d,%d);\n", dep_id_column, dep_id_row);
cou_putJS(cnx,JSOutBuf);
}
} /* for ... */
}
__CLEAR_RESULT