[GRASS-SVN] r36580 - grass/branches/releasebranch_6_3/db/drivers/dbf
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Apr 3 04:13:15 EDT 2009
Author: neteler
Date: 2009-04-03 04:13:15 -0400 (Fri, 03 Apr 2009)
New Revision: 36580
Modified:
grass/branches/releasebranch_6_3/db/drivers/dbf/dbfexe.c
Log:
mlennert: check for nulls and sort them to the end in ORDER BY clauses (merge from devel6, 36574)
Modified: grass/branches/releasebranch_6_3/db/drivers/dbf/dbfexe.c
===================================================================
--- grass/branches/releasebranch_6_3/db/drivers/dbf/dbfexe.c 2009-04-03 08:09:12 UTC (rev 36579)
+++ grass/branches/releasebranch_6_3/db/drivers/dbf/dbfexe.c 2009-04-03 08:13:15 UTC (rev 36580)
@@ -1,3 +1,4 @@
+
/*****************************************************************************
*
* MODULE: DBF driver
@@ -32,49 +33,65 @@
#define NODE_ERROR 4
int yyparse(void);
-void get_col_def ( SQLPSTMT *st, int col, int *type, int *width, int *decimals );
+
+void get_col_def(SQLPSTMT * st, int col, int *type, int *width,
+ int *decimals);
int sel(SQLPSTMT * st, int tab, int **set);
-void eval_val(int tab, int row, int col, SQLPVALUE * inval, SQLPVALUE * result);
+
+void eval_val(int tab, int row, int col, SQLPVALUE * inval,
+ SQLPVALUE * result);
int set_val(int tab, int row, int col, SQLPVALUE * val);
+
double eval_node(SQLPNODE *, int, int, SQLPVALUE *);
+
int eval_node_type(SQLPNODE *, int);
int execute(char *sql, cursor * c)
{
int i, j, tab, ret;
+
SQLPSTMT *st;
+
ROW *dbrows;
+
VALUE *dbval;
+
int row, nrows;
+
int *cols, ncols, col;
+
int *selset;
+
int dtype, stype;
+
int width, decimals;
+
char *tmpsql, name[500];
- SQLPVALUE *calctmp; /* store for calculated values in UPDATE, if any */
+ SQLPVALUE *calctmp; /* store for calculated values in UPDATE, if any */
+
/* parse sql statement */
/* I don't know why, but if the statement ends by string in quotes 'xxx' and is not
- * followed by space or '\n' it is not parsed properly -> */
- tmpsql = (char*) G_malloc ( strlen(sql) + 2 );
- sprintf ( tmpsql, "%s ", sql );
+ * followed by space or '\n' it is not parsed properly -> */
+ tmpsql = (char *)G_malloc(strlen(sql) + 2);
+ sprintf(tmpsql, "%s ", sql);
st = sqpInitStmt();
st->stmt = tmpsql;
sqpInitParser(st);
if (yyparse() != 0) {
- sqpFreeStmt(st);
- G_free ( tmpsql) ;
+ G_free(tmpsql);
append_error("SQL parser error: %s\n", st->errmsg);
append_error("in statement:\n%s\n", sql);
+ sqpFreeStmt(st);
return DB_FAILED;
}
- G_free ( tmpsql) ;
-
- G_debug (3, "SQL statement parsed successfully: %s", sql );
+ G_free(tmpsql);
- /* sqpPrintStmt(st); */ /* debug output only */
+ G_debug(3, "SQL statement parsed successfully: %s", sql);
+ /* sqpPrintStmt(st); *//* debug output only */
+
/* find table */
tab = find_table(st->table);
if (tab < 0 && st->command != SQLP_CREATE) {
@@ -85,40 +102,41 @@
/* For DROP we have to call load_table_head() because it reads permissions */
if ((st->command != SQLP_CREATE)) {
ret = load_table_head(tab);
- if ( ret == DB_FAILED ) {
- append_error( "Cannot load table head.\n");
+ if (ret == DB_FAILED) {
+ append_error("Cannot load table head.\n");
return DB_FAILED;
}
}
if ((st->command == SQLP_DROP) || (st->command == SQLP_DELETE) ||
- (st->command == SQLP_INSERT) || (st->command == SQLP_UPDATE) ||
- (st->command == SQLP_ADD_COLUMN) || (st->command == SQLP_DROP_COLUMN)
- ) {
- if ( db.tables[tab].write == FALSE ) {
- append_error( "Cannot modify table, don't have write permission for DBF file.\n");
+ (st->command == SQLP_INSERT) || (st->command == SQLP_UPDATE) ||
+ (st->command == SQLP_ADD_COLUMN) || (st->command == SQLP_DROP_COLUMN)
+ ) {
+ if (db.tables[tab].write == FALSE) {
+ append_error
+ ("Cannot modify table, don't have write permission for DBF file.\n");
return DB_FAILED;
}
}
-
+
/* find columns */
ncols = st->nCol;
if (st->command == SQLP_INSERT || st->command == SQLP_SELECT
|| st->command == SQLP_UPDATE || st->command == SQLP_DROP_COLUMN) {
if (ncols > 0) { /* colums were specified */
- cols = (int *) G_malloc (ncols * sizeof(int));
+ cols = (int *)G_malloc(ncols * sizeof(int));
for (i = 0; i < ncols; i++) {
cols[i] = find_column(tab, st->Col[i].s);
- if ( cols[i] == -1 ) {
- append_error( "Column '%s' not found\n", st->Col[i].s);
- return DB_FAILED;
+ if (cols[i] == -1) {
+ append_error("Column '%s' not found\n", st->Col[i].s);
+ return DB_FAILED;
}
}
}
else { /* all columns */
ncols = db.tables[tab].ncols;
- cols = (int *) G_malloc (ncols * sizeof(int));
+ cols = (int *)G_malloc(ncols * sizeof(int));
for (i = 0; i < ncols; i++)
cols[i] = i;
}
@@ -128,13 +146,13 @@
if (st->command == SQLP_INSERT || st->command == SQLP_UPDATE) {
for (i = 0; i < st->nVal; i++) {
col = cols[i];
- if ( st->Val[i].type != SQLP_NULL && st->Val[i].type != SQLP_EXPR) {
+ if (st->Val[i].type != SQLP_NULL && st->Val[i].type != SQLP_EXPR) {
dtype = db.tables[tab].cols[col].type;
stype = st->Val[i].type;
if ((dtype == DBF_INT && stype != SQLP_I)
|| (dtype == DBF_DOUBLE && stype == SQLP_S)
|| (dtype == DBF_CHAR && stype != SQLP_S)) {
- append_error("Incompatible value type.\n");
+ append_error("Incompatible value type.\n");
return DB_FAILED;
}
}
@@ -142,22 +160,25 @@
}
/* do command */
- G_debug(3,"Doing SQL command <%d> on DBF table... (see include/sqlp.h)", st->command);
+ G_debug(3, "Doing SQL command <%d> on DBF table... (see include/sqlp.h)",
+ st->command);
switch (st->command) {
case (SQLP_ADD_COLUMN):
load_table(tab);
- get_col_def ( st, 0, &dtype, &width, &decimals );
+ get_col_def(st, 0, &dtype, &width, &decimals);
ret = add_column(tab, dtype, st->Col[0].s, width, decimals);
- if ( ret == DB_FAILED ) {
+ if (ret == DB_FAILED) {
append_error("Cannot add column.\n");
return DB_FAILED;
}
/* Add column to each row */
- for ( i = 0; i < db.tables[tab].nrows; i++ ) {
- db.tables[tab].rows[i].values =
- (VALUE *) G_realloc ( db.tables[tab].rows[i].values, db.tables[tab].ncols * sizeof(VALUE));
-
- dbval = &(db.tables[tab].rows[i].values[db.tables[tab].ncols-1]);
+ for (i = 0; i < db.tables[tab].nrows; i++) {
+ db.tables[tab].rows[i].values =
+ (VALUE *) G_realloc(db.tables[tab].rows[i].values,
+ db.tables[tab].ncols * sizeof(VALUE));
+
+ dbval =
+ &(db.tables[tab].rows[i].values[db.tables[tab].ncols - 1]);
dbval->i = 0;
dbval->d = 0.0;
dbval->c = NULL;
@@ -165,10 +186,10 @@
}
db.tables[tab].updated = TRUE;
break;
-
+
case (SQLP_DROP_COLUMN):
load_table(tab);
- if (drop_column (tab, st->Col[0].s) != DB_OK) {
+ if (drop_column(tab, st->Col[0].s) != DB_OK) {
append_error("Cannot delete column.\n");
return DB_FAILED;
}
@@ -180,19 +201,19 @@
append_error("Table %s already exists\n", st->table);
return DB_FAILED;
}
- sprintf ( name, "%s.dbf", st->table );
- add_table(st->table, name );
-
+ sprintf(name, "%s.dbf", st->table);
+ add_table(st->table, name);
+
tab = find_table(st->table);
db.tables[tab].read = TRUE;
db.tables[tab].write = TRUE;
for (i = 0; i < ncols; i++) {
- get_col_def ( st, i, &dtype, &width, &decimals );
+ get_col_def(st, i, &dtype, &width, &decimals);
ret = add_column(tab, dtype, st->Col[i].s, width, decimals);
- if ( ret == DB_FAILED ) {
+ if (ret == DB_FAILED) {
append_error("Cannot create table.\n");
- db.tables[tab].alive = FALSE;
+ db.tables[tab].alive = FALSE;
return DB_FAILED;
}
}
@@ -213,20 +234,20 @@
if (db.tables[tab].nrows == db.tables[tab].arows) {
db.tables[tab].arows += 1000;
db.tables[tab].rows =
- (ROW *) G_realloc (db.tables[tab].rows,
- db.tables[tab].arows * sizeof(ROW));
+ (ROW *) G_realloc(db.tables[tab].rows,
+ db.tables[tab].arows * sizeof(ROW));
}
dbrows = db.tables[tab].rows;
row = db.tables[tab].nrows;
dbrows[row].values =
- (VALUE *) G_calloc (db.tables[tab].ncols, sizeof(VALUE));
+ (VALUE *) G_calloc(db.tables[tab].ncols, sizeof(VALUE));
dbrows[row].alive = TRUE;
-
+
/* set to null */
for (i = 0; i < db.tables[tab].ncols; i++) {
- VALUE *dbval;
+ VALUE *dbval;
- dbval = &(dbrows[row].values[i]);
+ dbval = &(dbrows[row].values[i]);
dbval->is_null = 1;
}
@@ -241,7 +262,7 @@
break;
case (SQLP_SELECT):
- G_debug ( 2, "SELECT");
+ G_debug(2, "SELECT");
c->st = st;
c->table = tab;
c->cols = cols;
@@ -266,7 +287,8 @@
/* update rows */
for (i = 0; i < nrows; i++) {
SQLPVALUE *temp_p;
- calctmp = (SQLPVALUE*)G_malloc((st->nVal) * sizeof(SQLPVALUE));
+
+ calctmp = (SQLPVALUE *) G_malloc((st->nVal) * sizeof(SQLPVALUE));
row = selset[i];
for (j = 0; j < st->nVal; j++) {
col = cols[j];
@@ -301,98 +323,100 @@
break;
}
- if ( st->command != SQLP_SELECT ) { /* because statement is released with cursor */
- sqpFreeStmt(st);
+ if (st->command != SQLP_SELECT) { /* because statement is released with cursor */
+ sqpFreeStmt(st);
}
return DB_OK;
}
/* for given parser result and column index finds dbf column definition */
-void get_col_def ( SQLPSTMT *st, int col, int *type, int *width, int *decimals )
+void get_col_def(SQLPSTMT * st, int col, int *type, int *width, int *decimals)
{
switch (st->ColType[col]) {
- case (SQLP_INTEGER):
- *type = DBF_INT;
- *width = 11;
- *decimals = 0;
- break;
- case (SQLP_VARCHAR):
- *type = DBF_CHAR;
- *width = st->ColWidth[col];
- *decimals = 0;
- break;
- case (SQLP_DATE): /* DATE treated as string unless SHAPELIB/DBFLIB supports date type */
- *type = DBF_CHAR;
- *width = 10; /* 2004-01-23 = 10 chars */
- *decimals = 0;
- break;
- case (SQLP_DOUBLE):
- *type = DBF_DOUBLE;
- *width = 20;
- *decimals = 6;
- break;
+ case (SQLP_INTEGER):
+ *type = DBF_INT;
+ *width = 11;
+ *decimals = 0;
+ break;
+ case (SQLP_VARCHAR):
+ *type = DBF_CHAR;
+ *width = st->ColWidth[col];
+ *decimals = 0;
+ break;
+ case (SQLP_DATE): /* DATE treated as string unless SHAPELIB/DBFLIB supports date type */
+ *type = DBF_CHAR;
+ *width = 10; /* 2004-01-23 = 10 chars */
+ *decimals = 0;
+ break;
+ case (SQLP_DOUBLE):
+ *type = DBF_DOUBLE;
+ *width = 20;
+ *decimals = 6;
+ break;
}
}
-void eval_val(int tab, int row, int col, SQLPVALUE * inval, SQLPVALUE *val)
+void eval_val(int tab, int row, int col, SQLPVALUE * inval, SQLPVALUE * val)
{
-
- double retval;
- /* XXX */
- if ( inval->type == SQLP_EXPR ) {
- retval = eval_node( inval->expr, tab, row, val );
- if ( retval == NODE_NULL )
- {
- val->type = SQLP_NULL;
+ double retval;
+
+ /* XXX */
+ if (inval->type == SQLP_EXPR) {
+
+ retval = eval_node(inval->expr, tab, row, val);
+ if (retval == NODE_NULL) {
+ val->type = SQLP_NULL;
}
- else if ( retval == NODE_TRUE )
- {
- val->i = 1;
- val->d = 1.0;
- val->s = "TRUE";
+ else if (retval == NODE_TRUE) {
+ val->i = 1;
+ val->d = 1.0;
+ val->s = "TRUE";
}
- else if ( retval == NODE_FALSE )
- {
- val->i = 0;
- val->d = 0.0;
- val->s = NULL;
+ else if (retval == NODE_FALSE) {
+ val->i = 0;
+ val->d = 0.0;
+ val->s = NULL;
}
- else if ( retval == NODE_VALUE )
- {
- /* Ok, got a value, propagate it to the proper type */
- if( val->type == SQLP_I ){
- val->d = (double)val->i;
- val->s = (char*)G_malloc (32*sizeof(char));
- sprintf( val->s, "%d", val->i );
- }else if( val->type == SQLP_D ){
- val->i = (int)val->d;
- val->s = (char*)G_malloc (32*sizeof(char));
- sprintf( val->s, "%g", val->d );
- }else if( val->type == SQLP_S ){
- val->i = atoi( val->s );
- val->d = atof( val->s );
- }else{
- G_fatal_error("This should not happen: wrong return type in parsing.");
- }
+ else if (retval == NODE_VALUE) {
+ /* Ok, got a value, propagate it to the proper type */
+ if (val->type == SQLP_I) {
+ val->d = (double)val->i;
+ val->s = (char *)G_malloc(32 * sizeof(char));
+ sprintf(val->s, "%d", val->i);
+ }
+ else if (val->type == SQLP_D) {
+ val->i = (int)val->d;
+ val->s = (char *)G_malloc(32 * sizeof(char));
+ sprintf(val->s, "%g", val->d);
+ }
+ else if (val->type == SQLP_S) {
+ val->i = atoi(val->s);
+ val->d = atof(val->s);
+ }
+ else {
+ G_fatal_error
+ ("This should not happen: wrong return type in parsing.");
+ }
}
- else if ( retval == NODE_ERROR )
- {
- G_fatal_error("This should not happen: got a wrong expression structure after parsing.");
+ else if (retval == NODE_ERROR) {
+ G_fatal_error
+ ("This should not happen: got a wrong expression structure after parsing.");
}
- else
- {
- G_fatal_error("Unknown return value calling eval_node from eval_val");
+ else {
+ G_fatal_error
+ ("Unknown return value calling eval_node from eval_val");
}
- }else{
- /*
- * TODO: maybe use this function to perform type "conversion",
- * i.e. setting all of s,i,d to the same "value",as is done with
- * the result of eval_node above.
- */
- val = inval;
}
+ else {
+ /*
+ * TODO: maybe use this function to perform type "conversion",
+ * i.e. setting all of s,i,d to the same "value",as is done with
+ * the result of eval_node above.
+ */
+ val = inval;
+ }
}
int set_val(int tab, int row, int col, SQLPVALUE * val)
@@ -400,54 +424,55 @@
VALUE *dbval;
dbval = &(db.tables[tab].rows[row].values[col]);
-/* For debugging purposes; see FIXME below
- fprintf(stderr, "In set_val : ");
- fprintf(stderr, val->type==SQLP_EXPR?"sqlp_expr":
- val->type==SQLP_NULL?"sqlp_null":
- val->type==SQLP_I?"sqlp_i":
- val->type==SQLP_D?"sqlp_d":
- val->type==SQLP_S?"sqlp_s":
- "other"); //DCA
- fprintf(stderr,"%d\n",val->type);
- fflush(stderr);
-*/
- if ( val->type == SQLP_EXPR ){
- eval_val( tab, row, col, val, val );
+ /* For debugging purposes; see FIXME below
+ fprintf(stderr, "In set_val : ");
+ fprintf(stderr, val->type==SQLP_EXPR?"sqlp_expr":
+ val->type==SQLP_NULL?"sqlp_null":
+ val->type==SQLP_I?"sqlp_i":
+ val->type==SQLP_D?"sqlp_d":
+ val->type==SQLP_S?"sqlp_s":
+ "other"); //DCA
+ fprintf(stderr,"%d\n",val->type);
+ fflush(stderr);
+ */
+ if (val->type == SQLP_EXPR) {
+ eval_val(tab, row, col, val, val);
}
/* FIXME: SQLP_NULL is not always properly detected.
* This workaround works, since type should be some of these
* after passing through eval_val; otherwise it is NULL
*/
- if ( ! ( val->type == SQLP_I
- || val->type == SQLP_D
- || val->type == SQLP_S ) ) {
- dbval->is_null = 1;
+ if (!(val->type == SQLP_I || val->type == SQLP_D || val->type == SQLP_S)) {
+ dbval->is_null = 1;
dbval->c = NULL;
dbval->i = 0;
dbval->d = 0.0;
- } else {
- dbval->is_null = 0;
+ }
+ else {
+ dbval->is_null = 0;
switch (db.tables[tab].cols[col].type) {
- case DBF_INT:
- dbval->i = val->i;
- break;
- case DBF_CHAR:
- save_string(dbval, val->s);
- break;
- case DBF_DOUBLE:
- if (val->type == SQLP_I)
- dbval->d = val->i;
- else if (val->type == SQLP_D)
- dbval->d = val->d;
- else if (val->type == SQLP_S) {
- char* tailptr;
- double dval = strtod (val->s, &tailptr);
- if (!(*tailptr)) {
- dbval->d = dval;
- }
+ case DBF_INT:
+ dbval->i = val->i;
+ break;
+ case DBF_CHAR:
+ save_string(dbval, val->s);
+ break;
+ case DBF_DOUBLE:
+ if (val->type == SQLP_I)
+ dbval->d = val->i;
+ else if (val->type == SQLP_D)
+ dbval->d = val->d;
+ else if (val->type == SQLP_S) {
+ char *tailptr;
+
+ double dval = strtod(val->s, &tailptr);
+
+ if (!(*tailptr)) {
+ dbval->d = dval;
}
- break;
+ }
+ break;
}
}
return (1);
@@ -455,116 +480,155 @@
/* Comparison of 2 rows */
static int cur_cmp_table;
+
static int cur_cmp_ocol;
-static int cmp_row_asc ( const void *pa, const void *pb )
+
+static int cmp_row_asc(const void *pa, const void *pb)
{
- int *row1 = (int*) pa;
- int *row2 = (int*) pb;
+ int *row1 = (int *)pa;
+
+ int *row2 = (int *)pb;
+
char *c1, *c2;
+
int i1, i2;
+
double d1, d2;
+
TABLE *tbl;
tbl = &(db.tables[cur_cmp_table]);
-
- switch ( tbl->cols[cur_cmp_ocol].type ) {
- case DBF_CHAR:
- c1 = tbl->rows[*row1].values[cur_cmp_ocol].c;
- c2 = tbl->rows[*row2].values[cur_cmp_ocol].c;
- return ( strcmp(c1, c2) );
- break;
- case DBF_INT:
- i1 = tbl->rows[*row1].values[cur_cmp_ocol].i;
- i2 = tbl->rows[*row2].values[cur_cmp_ocol].i;
- if ( i1 < i2 ) return -1;
- if ( i1 > i2 ) return 1;
+
+ if (tbl->rows[*row1].values[cur_cmp_ocol].is_null) {
+ if (tbl->rows[*row2].values[cur_cmp_ocol].is_null) {
return 0;
- break;
- case DBF_DOUBLE:
- d1 = tbl->rows[*row1].values[cur_cmp_ocol].d;
- d2 = tbl->rows[*row2].values[cur_cmp_ocol].d;
- if ( d1 < d2 ) return -1;
- if ( d1 > d2 ) return 1;
+ }
+ else {
+ return 1;
+ }
+ }
+ else {
+ if (tbl->rows[*row2].values[cur_cmp_ocol].is_null) {
+ return -1;
+ }
+ else {
+ switch (tbl->cols[cur_cmp_ocol].type) {
+ case DBF_CHAR:
+ c1 = tbl->rows[*row1].values[cur_cmp_ocol].c;
+ c2 = tbl->rows[*row2].values[cur_cmp_ocol].c;
+ return (strcmp(c1, c2));
+ break;
+ case DBF_INT:
+ i1 = tbl->rows[*row1].values[cur_cmp_ocol].i;
+ i2 = tbl->rows[*row2].values[cur_cmp_ocol].i;
+ if (i1 < i2)
+ return -1;
+ if (i1 > i2)
+ return 1;
+ return 0;
+ break;
+ case DBF_DOUBLE:
+ d1 = tbl->rows[*row1].values[cur_cmp_ocol].d;
+ d2 = tbl->rows[*row2].values[cur_cmp_ocol].d;
+ if (d1 < d2)
+ return -1;
+ if (d1 > d2)
+ return 1;
+ return 0;
+ break;
+ }
return 0;
- break;
+ }
}
- return 0;
}
-static int cmp_row_desc ( const void *pa, const void *pb )
+static int cmp_row_desc(const void *pa, const void *pb)
{
-
- return -cmp_row_asc (pa, pb);
+ return -cmp_row_asc(pa, pb);
+
}
/* Select records, sets 'selset' to new array of items and returns
-* number of items or -1 for error */
+ * number of items or -1 for error */
int sel(SQLPSTMT * st, int tab, int **selset)
{
int i, ret, condition;
+
int *set; /* pointer to array of indexes to rows */
+
int aset, nset;
- G_debug ( 2, "sel(): tab = %d", tab);
+ G_debug(2, "sel(): tab = %d", tab);
*selset = NULL;
nset = 0;
ret = load_table(tab);
- if ( ret == DB_FAILED ) {
- append_error( "Cannot load table.\n");
+ if (ret == DB_FAILED) {
+ append_error("Cannot load table.\n");
return -1;
}
aset = 1;
- set = (int *) G_malloc (aset * sizeof(int));
+ set = (int *)G_malloc(aset * sizeof(int));
if (st->upperNodeptr) {
int node_type;
+
/* First eval node type */
- node_type = eval_node_type( st->upperNodeptr, tab);
+ node_type = eval_node_type(st->upperNodeptr, tab);
G_debug(4, "node result type = %d", node_type);
-
- if ( node_type == -1 ) {
- append_error( "Incompatible types in WHERE condition.\n");
+
+ if (node_type == -1) {
+ append_error("Incompatible types in WHERE condition.\n");
return -1;
- } else if ( node_type == SQLP_S || node_type == SQLP_I || node_type == SQLP_D ) {
- append_error( "Result of WHERE condition is not of type BOOL.\n");
+ }
+ else if (node_type == SQLP_S || node_type == SQLP_I ||
+ node_type == SQLP_D) {
+ append_error("Result of WHERE condition is not of type BOOL.\n");
return -1;
- } else if ( node_type == SQLP_NULL ) {
+ }
+ else if (node_type == SQLP_NULL) {
/* Conditions has undefined result -> nothing selected */
return 0;
- } else if ( node_type == SQLP_BOOL ) {
+ }
+ else if (node_type == SQLP_BOOL) {
for (i = 0; i < db.tables[tab].nrows; i++) {
SQLPVALUE value;
G_debug(4, "row %d", i);
- condition = eval_node( st->upperNodeptr, tab, i, &value);
+ condition = eval_node(st->upperNodeptr, tab, i, &value);
G_debug(4, "condition = %d", condition);
- if ( condition == NODE_ERROR ) { /* e.g. division by 0 */
- append_error( "Error in evaluation of WHERE condition.\n");
+ if (condition == NODE_ERROR) { /* e.g. division by 0 */
+ append_error("Error in evaluation of WHERE condition.\n");
return (-1);
- } else if ( condition == NODE_TRUE ) { /* true */
+ }
+ else if (condition == NODE_TRUE) { /* true */
if (nset == aset) {
aset += 1000;
- set = (int *) G_realloc (set, aset * sizeof(int));
+ set = (int *)G_realloc(set, aset * sizeof(int));
}
set[nset] = i;
nset++;
- } else if ( condition != NODE_FALSE && condition != NODE_NULL ) { /* Should not happen */
- append_error( "Unknown result (%d) of WHERE evaluation.\n", condition);
- return -1;
}
+ else if (condition != NODE_FALSE && condition != NODE_NULL) { /* Should not happen */
+ append_error("Unknown result (%d) of WHERE evaluation.\n",
+ condition);
+ return -1;
+ }
}
- } else { /* Should not happen */
- append_error( "Unknown WHERE condition type (bug in DBF driver).\n");
+ }
+ else { /* Should not happen */
+ append_error
+ ("Unknown WHERE condition type (bug in DBF driver).\n");
return -1;
}
- } else { /* Select all */
+ }
+ else { /* Select all */
aset = db.tables[tab].nrows;
- set = (int *) G_realloc (set, aset * sizeof(int));
+ set = (int *)G_realloc(set, aset * sizeof(int));
for (i = 0; i < db.tables[tab].nrows; i++) {
set[i] = i;
}
@@ -572,33 +636,33 @@
}
/* Order */
- if ( st->command == SQLP_SELECT && st->orderCol ) {
+ if (st->command == SQLP_SELECT && st->orderCol) {
G_debug(3, "Order selection by %s", st->orderCol);
-
- /* Find order col */
+
+ /* Find order col */
cur_cmp_ocol = -1;
- for ( i = 0; i < db.tables[tab].ncols; i++ ) {
- if ( strcmp ( db.tables[tab].cols[i].name, st->orderCol ) == 0 ) {
+ for (i = 0; i < db.tables[tab].ncols; i++) {
+ if (strcmp(db.tables[tab].cols[i].name, st->orderCol) == 0) {
cur_cmp_ocol = i;
break;
}
}
- if ( cur_cmp_ocol < 0 ) {
- append_error( "Cannot find order column '%s'\n", st->orderCol);
+ if (cur_cmp_ocol < 0) {
+ append_error("Cannot find order column '%s'\n", st->orderCol);
return -1;
}
cur_cmp_table = tab;
- if (st->orderDir == SORT_DESC )
- {
- qsort(set, nset, sizeof(int), cmp_row_desc);
- } else {
- qsort(set, nset, sizeof(int), cmp_row_asc);
+ if (st->orderDir == SORT_DESC) {
+ qsort(set, nset, sizeof(int), cmp_row_desc);
}
+ else {
+ qsort(set, nset, sizeof(int), cmp_row_asc);
+ }
-
+
}
-
+
*selset = set;
return nset;
}
@@ -616,278 +680,307 @@
* If results is NODE_VALUE, the 'value' is set, if value is type SQLP_S the string is not duplicated
* and only pointer is set -> do not free value->s
*/
-double eval_node(SQLPNODE *nptr, int tab, int row, SQLPVALUE *value)
+double eval_node(SQLPNODE * nptr, int tab, int row, SQLPVALUE * value)
{
- int left, right;
+ int left, right;
+
SQLPVALUE left_value, right_value;
- int ccol;
+
+ int ccol;
+
COLUMN *col;
- VALUE *val;
+
+ VALUE *val;
+
double left_dval, right_dval, dval;
- char *rightbuf;
+ char *rightbuf;
+
/* Note: node types were previously checked by eval_node_type */
- G_debug ( 4, "eval_node node_type = %d", nptr->node_type );
+ G_debug(4, "eval_node node_type = %d", nptr->node_type);
- switch ( nptr->node_type) {
- case SQLP_NODE_VALUE:
- if ( nptr->value.type == SQLP_NULL )
- return NODE_NULL;
-
- value->type = nptr->value.type;
- value->s = nptr->value.s;
- value->i = nptr->value.i;
- value->d = nptr->value.d;
- return NODE_VALUE;
+ switch (nptr->node_type) {
+ case SQLP_NODE_VALUE:
+ if (nptr->value.type == SQLP_NULL)
+ return NODE_NULL;
+
+ value->type = nptr->value.type;
+ value->s = nptr->value.s;
+ value->i = nptr->value.i;
+ value->d = nptr->value.d;
+ return NODE_VALUE;
+ break;
+
+ case SQLP_NODE_COLUMN:
+ ccol = find_column(tab, nptr->column_name);
+ col = &(db.tables[tab].cols[ccol]);
+ val = &(db.tables[tab].rows[row].values[ccol]);
+
+ if (val->is_null)
+ return NODE_NULL;
+
+ switch (col->type) {
+ case DBF_CHAR:
+ value->s = val->c;
+ value->type = SQLP_S;
break;
+ case DBF_INT:
+ value->i = val->i;
+ value->type = SQLP_I;
+ break;
+ case DBF_DOUBLE:
+ value->d = val->d;
+ value->type = SQLP_D;
+ break;
+ }
+ return NODE_VALUE;
+ break;
- case SQLP_NODE_COLUMN:
- ccol = find_column(tab, nptr->column_name);
- col = &(db.tables[tab].cols[ccol]);
- val = &(db.tables[tab].rows[row].values[ccol]);
+ case SQLP_NODE_EXPRESSION:
+ /* Note: Some expressions (e.g. NOT) have only one side */
+ if (nptr->left) {
+ left = eval_node(nptr->left, tab, row, &left_value);
+ G_debug(4, " left = %d", left);
- if ( val->is_null )
- return NODE_NULL;
+ if (left == NODE_ERROR)
+ return NODE_ERROR;
- switch (col->type) {
- case DBF_CHAR:
- value->s = val->c;
- value->type = SQLP_S;
- break;
- case DBF_INT:
- value->i = val->i;
- value->type = SQLP_I;
- break;
- case DBF_DOUBLE:
- value->d = val->d;
- value->type = SQLP_D;
- break;
+ if (left != NODE_NULL) {
+ if (left_value.type == SQLP_I)
+ left_dval = left_value.i;
+ else
+ left_dval = left_value.d;
+
+ G_debug(4, " left_dval = %f", left_dval);
}
- return NODE_VALUE;
- break;
+ }
- case SQLP_NODE_EXPRESSION:
- /* Note: Some expressions (e.g. NOT) have only one side */
- if ( nptr->left ) {
- left = eval_node ( nptr->left, tab, row, &left_value);
- G_debug ( 4, " left = %d", left );
+ if (nptr->right) {
+ right = eval_node(nptr->right, tab, row, &right_value);
+ G_debug(4, " right = %d", right);
- if ( left == NODE_ERROR )
- return NODE_ERROR;
+ if (right == NODE_ERROR)
+ return NODE_ERROR;
- if ( left != NODE_NULL ) {
- if ( left_value.type == SQLP_I )
- left_dval = left_value.i;
- else
- left_dval = left_value.d;
-
- G_debug ( 4, " left_dval = %f", left_dval );
- }
+ if (right != NODE_NULL) {
+ if (right_value.type == SQLP_I)
+ right_dval = right_value.i;
+ else
+ right_dval = right_value.d;
+
+ G_debug(4, " right_dval = %f", right_dval);
}
+ }
- if ( nptr->right ) {
- right = eval_node ( nptr->right, tab, row, &right_value);
- G_debug ( 4, " right = %d", right );
+ G_debug(4, " operator = %d", nptr->oper);
- if ( right == NODE_ERROR )
- return NODE_ERROR;
+ switch (nptr->oper) {
+ /* Arithmetical */
+ case SQLP_ADD:
+ case SQLP_SUBTR:
+ case SQLP_MLTP:
+ case SQLP_DIV:
+ if (left == NODE_NULL || right == NODE_NULL)
+ return NODE_NULL;
- if ( right != NODE_NULL ) {
- if ( right_value.type == SQLP_I )
- right_dval = right_value.i;
- else
- right_dval = right_value.d;
-
- G_debug ( 4, " right_dval = %f", right_dval );
+ switch (nptr->oper) {
+ case SQLP_ADD:
+ dval = left_dval + right_dval;
+ break;
+ case SQLP_SUBTR:
+ dval = left_dval - right_dval;
+ break;
+ case SQLP_MLTP:
+ dval = left_dval * right_dval;
+ break;
+ case SQLP_DIV:
+ if (right_dval != 0.0) {
+ dval = left_dval / right_dval;
}
+ else {
+ append_error("Division by zero\n");
+ return NODE_ERROR;
+ }
+ break;
}
-
- G_debug ( 4, " operator = %d", nptr->oper );
- switch ( nptr->oper ) {
- /* Arithmetical */
- case SQLP_ADD:
- case SQLP_SUBTR:
- case SQLP_MLTP:
- case SQLP_DIV:
- if ( left == NODE_NULL || right == NODE_NULL )
- return NODE_NULL;
+ if (left_value.type == SQLP_I && right_value.type == SQLP_I &&
+ (nptr->oper == SQLP_ADD || nptr->oper == SQLP_SUBTR ||
+ nptr->oper == SQLP_MLTP)) {
+ value->type = SQLP_I;
+ value->i = (int)dval;
+ }
+ else {
+ value->type = SQLP_D;
+ value->d = dval;
+ }
+ return NODE_VALUE;
- switch ( nptr->oper ) {
- case SQLP_ADD:
- dval = left_dval + right_dval;
- break;
- case SQLP_SUBTR:
- dval = left_dval - right_dval;
- break;
- case SQLP_MLTP:
- dval = left_dval * right_dval;
- break;
- case SQLP_DIV:
- if ( right_dval != 0.0) {
- dval = left_dval / right_dval;
- } else {
- append_error ("Division by zero\n");
- return NODE_ERROR;
- }
- break;
- }
-
- if ( left_value.type == SQLP_I && right_value.type == SQLP_I &&
- ( nptr->oper == SQLP_ADD || nptr->oper == SQLP_SUBTR || nptr->oper == SQLP_MLTP ) )
- {
- value->type = SQLP_I;
- value->i = (int) dval;
- } else {
- value->type = SQLP_D;
- value->d = dval;
- }
- return NODE_VALUE;
+ break;
- break;
+ /* Comparison */
+ /* Operators valid for all type */
+ case SQLP_EQ:
+ if (left == NODE_NULL || right == NODE_NULL) {
+ return NODE_NULL;
+ }
+ else if (left_value.type == SQLP_S) { /* we checked before if right is also string */
+ if (left_value.s && right_value.s &&
+ strcmp(left_value.s, right_value.s) == 0)
+ return NODE_TRUE;
+ else
+ return NODE_FALSE;
+ }
+ else { /* numbers */
+ if (left_dval == right_dval)
+ return NODE_TRUE;
+ else
+ return NODE_FALSE;
+ }
+ break;
- /* Comparison */
- /* Operators valid for all type */
- case SQLP_EQ:
- if ( left == NODE_NULL || right == NODE_NULL ) {
- return NODE_NULL;
- } else if ( left_value.type == SQLP_S ) { /* we checked before if right is also string */
- if ( left_value.s && right_value.s && strcmp(left_value.s,right_value.s) == 0)
- return NODE_TRUE;
- else
- return NODE_FALSE;
- } else { /* numbers */
- if ( left_dval == right_dval )
- return NODE_TRUE;
- else
- return NODE_FALSE;
- }
- break;
+ case SQLP_NE:
+ if (left == NODE_NULL || right == NODE_NULL) {
+ return NODE_NULL;
+ }
+ else if (left_value.type == SQLP_S) { /* we checked before if right is also string */
+ if (left_value.s && right_value.s &&
+ strcmp(left_value.s, right_value.s) != 0)
+ return NODE_TRUE;
+ else
+ return NODE_FALSE;
+ }
+ else { /* numbers */
+ if (left_dval != right_dval)
+ return NODE_TRUE;
+ else
+ return NODE_FALSE;
+ }
- case SQLP_NE:
- if ( left == NODE_NULL || right == NODE_NULL ) {
- return NODE_NULL;
- } else if ( left_value.type == SQLP_S ) { /* we checked before if right is also string */
- if ( left_value.s && right_value.s && strcmp(left_value.s,right_value.s) != 0)
- return NODE_TRUE;
- else
- return NODE_FALSE;
- } else { /* numbers */
- if ( left_dval != right_dval )
- return NODE_TRUE;
- else
- return NODE_FALSE;
- }
+ /* Operators valid for numbers */
+ case SQLP_LT:
+ if (left == NODE_NULL || right == NODE_NULL) {
+ return NODE_NULL;
+ }
+ else {
+ if (left_dval < right_dval)
+ return NODE_TRUE;
+ else
+ return NODE_FALSE;
+ }
- /* Operators valid for numbers */
- case SQLP_LT:
- if ( left == NODE_NULL || right == NODE_NULL ) {
- return NODE_NULL;
- } else {
- if ( left_dval < right_dval )
- return NODE_TRUE;
- else
- return NODE_FALSE;
- }
+ case SQLP_LE:
+ if (left == NODE_NULL || right == NODE_NULL) {
+ return NODE_NULL;
+ }
+ else {
+ if (left_dval <= right_dval)
+ return NODE_TRUE;
+ else
+ return NODE_FALSE;
+ }
- case SQLP_LE:
- if ( left == NODE_NULL || right == NODE_NULL ) {
- return NODE_NULL;
- } else {
- if ( left_dval <= right_dval )
- return NODE_TRUE;
- else
- return NODE_FALSE;
- }
+ case SQLP_GT:
+ if (left == NODE_NULL || right == NODE_NULL) {
+ return NODE_NULL;
+ }
+ else {
+ if (left_dval > right_dval)
+ return NODE_TRUE;
+ else
+ return NODE_FALSE;
+ }
- case SQLP_GT:
- if ( left == NODE_NULL || right == NODE_NULL ) {
- return NODE_NULL;
- } else {
- if ( left_dval > right_dval )
- return NODE_TRUE;
- else
- return NODE_FALSE;
- }
+ case SQLP_GE:
+ if (left == NODE_NULL || right == NODE_NULL) {
+ return NODE_NULL;
+ }
+ else {
+ if (left_dval >= right_dval)
+ return NODE_TRUE;
+ else
+ return NODE_FALSE;
+ }
- case SQLP_GE:
- if ( left == NODE_NULL || right == NODE_NULL ) {
- return NODE_NULL;
- } else {
- if ( left_dval >= right_dval )
- return NODE_TRUE;
- else
- return NODE_FALSE;
- }
+ /* Operator valid for string */
+ case SQLP_MTCH:
+ if (left == NODE_NULL || right == NODE_NULL) {
+ return NODE_NULL;
+ }
+ else {
+ /* hack to get '%substring' and 'substring%' working */
+ rightbuf = G_str_replace(right_value.s, "%", "");
+ G_chop(rightbuf);
+ if (left_value.s && right_value.s &&
+ strstr(left_value.s, rightbuf) != NULL) {
+ G_free(rightbuf);
+ return NODE_TRUE;
+ }
+ else {
+ G_free(rightbuf);
+ return NODE_FALSE;
+ }
+ }
- /* Operator valid for string */
- case SQLP_MTCH:
- if ( left == NODE_NULL || right == NODE_NULL ) {
- return NODE_NULL;
- } else {
- /* hack to get '%substring' and 'substring%' working */
- rightbuf = G_str_replace ( right_value.s, "%", "" );
- G_chop (rightbuf);
- if ( left_value.s && right_value.s && strstr(left_value.s,rightbuf) != NULL){
- G_free (rightbuf);
- return NODE_TRUE;
- }
- else{
- G_free (rightbuf);
- return NODE_FALSE;
- }
- }
+ case SQLP_ISNULL:
+ return right == NODE_NULL ? NODE_TRUE : NODE_FALSE;
- case SQLP_ISNULL:
- return right == NODE_NULL ? NODE_TRUE : NODE_FALSE;
+ case SQLP_NOTNULL:
+ return right != NODE_NULL ? NODE_TRUE : NODE_FALSE;
- case SQLP_NOTNULL:
- return right != NODE_NULL ? NODE_TRUE : NODE_FALSE;
+ /* Logical */
+ case SQLP_AND:
+ if (left == NODE_NULL || right == NODE_NULL) {
+ return NODE_NULL;
+ }
+ else if (left == NODE_TRUE && right == NODE_TRUE) {
+ return NODE_TRUE;
+ }
+ else if (left == NODE_VALUE || right == NODE_VALUE) { /* Should not happen */
+ append_error("Value operand for AND\n");
+ return NODE_ERROR;
+ }
+ else {
+ return NODE_FALSE;
+ }
+ case SQLP_OR:
+ if (left == NODE_NULL && right == NODE_NULL) {
+ return NODE_NULL;
+ }
+ else if (left == NODE_TRUE || right == NODE_TRUE) {
+ return NODE_TRUE;
+ }
+ else if (left == NODE_VALUE || right == NODE_VALUE) { /* Should not happen */
+ append_error("Value operand for OR\n");
+ return NODE_ERROR;
+ }
+ else {
+ return NODE_FALSE;
+ }
+ case SQLP_NOT:
+ /* sub node stored on the right side */
+ if (right == NODE_NULL) {
+ return NODE_NULL;
+ }
+ else if (right == NODE_TRUE) {
+ return NODE_FALSE;
+ }
+ else if (right == NODE_VALUE) { /* Should not happen */
+ append_error("Value operand for NOT\n");
+ return NODE_ERROR;
+ }
+ else {
+ return NODE_TRUE;
+ }
- /* Logical */
- case SQLP_AND:
- if ( left == NODE_NULL || right == NODE_NULL ) {
- return NODE_NULL;
- } else if ( left == NODE_TRUE && right == NODE_TRUE ) {
- return NODE_TRUE;
- } else if ( left == NODE_VALUE || right == NODE_VALUE ) { /* Should not happen */
- append_error ("Value operand for AND\n");
- return NODE_ERROR;
- } else {
- return NODE_FALSE;
- }
- case SQLP_OR:
- if ( left == NODE_NULL && right == NODE_NULL ) {
- return NODE_NULL;
- } else if ( left == NODE_TRUE || right == NODE_TRUE ) {
- return NODE_TRUE;
- } else if ( left == NODE_VALUE || right == NODE_VALUE ) { /* Should not happen */
- append_error ("Value operand for OR\n");
- return NODE_ERROR;
- } else {
- return NODE_FALSE;
- }
- case SQLP_NOT:
- /* sub node stored on the right side */
- if ( right == NODE_NULL ) {
- return NODE_NULL;
- } else if ( right == NODE_TRUE ) {
- return NODE_FALSE;
- } else if ( right == NODE_VALUE ) { /* Should not happen */
- append_error ("Value operand for NOT\n");
- return NODE_ERROR;
- } else {
- return NODE_TRUE;
- }
+ default:
+ append_error("Unknown operator %d\n", nptr->oper);
+ return NODE_FALSE;
+ }
+ }
- default:
- append_error ("Unknown operator %d\n", nptr->oper);
- return NODE_FALSE;
- }
- }
-
- return NODE_ERROR; /* Not reached */
+ return NODE_ERROR; /* Not reached */
}
/* Recursively get value/expression type.
@@ -928,148 +1021,165 @@
* Logical expressions
* In general, if we know that the result is NULL regardless actual values it returns SQLP_NULL
* so that tests for individual rows are not performed, otherwise SQLP_BOOL
- * SQLP_BOOL SQLP_BOOL AND -> SQLP_BOOL
- * SQLP_BOOL SQLP_NULL AND -> SQLP_NULL
- * SQLP_NULL SQLP_NULL AND -> SQLP_NULL
- * SQLP_BOOL SQLP_BOOL OR -> SQLP_BOOL
- * SQLP_BOOL SQLP_NULL OR -> SQLP_BOOL
- * SQLP_NULL SQLP_NULL OR -> SQLP_NULL
- * SQLP_BOOL - NOT -> SQLP_BOOL
- * SQLP_NULL - NOT -> SQLP_NULL
+ * SQLP_BOOL SQLP_BOOL AND -> SQLP_BOOL
+ * SQLP_BOOL SQLP_NULL AND -> SQLP_NULL
+ * SQLP_NULL SQLP_NULL AND -> SQLP_NULL
+ * SQLP_BOOL SQLP_BOOL OR -> SQLP_BOOL
+ * SQLP_BOOL SQLP_NULL OR -> SQLP_BOOL
+ * SQLP_NULL SQLP_NULL OR -> SQLP_NULL
+ * SQLP_BOOL - NOT -> SQLP_BOOL
+ * SQLP_NULL - NOT -> SQLP_NULL
*/
-int eval_node_type(SQLPNODE *nptr, int tab ) {
+int eval_node_type(SQLPNODE * nptr, int tab)
+{
int left, right;
+
int ccol;
+
COLUMN *col = NULL;
- switch ( nptr->node_type) {
- case SQLP_NODE_VALUE:
- return nptr->value.type;
+ switch (nptr->node_type) {
+ case SQLP_NODE_VALUE:
+ return nptr->value.type;
+ break;
+
+ case SQLP_NODE_COLUMN:
+ ccol = find_column(tab, nptr->column_name);
+ if (ccol == -1) {
+ append_error("Column '%s' not found\n", nptr->column_name);
+ return (-1);
+ }
+ col = &(db.tables[tab].cols[ccol]);
+ switch (col->type) {
+ case DBF_CHAR:
+ return (SQLP_S);
break;
+ case DBF_INT:
+ return (SQLP_I);
+ break;
+ case DBF_DOUBLE:
+ return (SQLP_D);
+ break;
+ }
+ break;
- case SQLP_NODE_COLUMN:
- ccol = find_column ( tab, nptr->column_name );
- if ( ccol == -1 ) {
- append_error ("Column '%s' not found\n", nptr->column_name);
- return (-1);
+ case SQLP_NODE_EXPRESSION:
+ /* Note: Some expressions (e.g. NOT) have only one side */
+ if (nptr->left) {
+ left = eval_node_type(nptr->left, tab);
+ if (left == -1)
+ return -1;
+ }
+
+ if (nptr->right) {
+ right = eval_node_type(nptr->right, tab);
+ if (right == -1)
+ return -1;
+ }
+
+ switch (nptr->oper) {
+ /* Arithmetical */
+ case SQLP_ADD:
+ case SQLP_SUBTR:
+ case SQLP_MLTP:
+ case SQLP_DIV:
+ if (left == SQLP_S || right == SQLP_S) {
+ append_error
+ ("Arithmetical operation with strings is not allowed\n");
+ return -1;
}
- col = &(db.tables[tab].cols[ccol]);
- switch (col->type) {
- case DBF_CHAR:
- return (SQLP_S);
- break;
- case DBF_INT:
- return (SQLP_I);
- break;
- case DBF_DOUBLE:
- return (SQLP_D);
- break;
+ else if (left == SQLP_NULL || right == SQLP_NULL) {
+ return SQLP_NULL;
}
+ else if (left == SQLP_I && right == SQLP_I &&
+ (nptr->oper == SQLP_ADD || nptr->oper == SQLP_SUBTR ||
+ nptr->oper == SQLP_MLTP)) {
+ return SQLP_I;
+ }
+ else {
+ return SQLP_D;
+ }
break;
- case SQLP_NODE_EXPRESSION:
- /* Note: Some expressions (e.g. NOT) have only one side */
- if ( nptr->left ) {
- left = eval_node_type( nptr->left, tab);
- if ( left == -1 )
- return -1;
+ /* Comparison */
+ /* Operators valid for all type */
+ case SQLP_EQ:
+ case SQLP_NE:
+ if ((left == SQLP_S && (right == SQLP_I || right == SQLP_D)) ||
+ (right == SQLP_S && (left == SQLP_I || left == SQLP_D))) {
+ append_error
+ ("Comparison between string and number is not allowed\n");
+ return -1;
}
-
- if ( nptr->right ) {
- right = eval_node_type( nptr->right, tab);
- if ( right == -1 )
- return -1;
+ else if (left == SQLP_NULL || right == SQLP_NULL) {
+ return SQLP_NULL;
}
+ else {
+ return SQLP_BOOL;
+ }
+ /* Operators valid for numbers */
+ case SQLP_LT:
+ case SQLP_LE:
+ case SQLP_GT:
+ case SQLP_GE:
+ if (left == SQLP_S || right == SQLP_S) {
+ append_error("Comparison '%s' between strings not allowed\n",
+ sqpOperatorName(nptr->oper));
+ return -1;
+ }
+ else if (left == SQLP_NULL || right == SQLP_NULL) {
+ return SQLP_NULL;
+ }
+ else {
+ return SQLP_BOOL;
+ }
+ /* Operator valid for string */
+ case SQLP_MTCH:
+ if (left == SQLP_I || left == SQLP_D || right == SQLP_I ||
+ right == SQLP_D) {
+ append_error("Match (~) between numbers not allowed\n");
+ return -1;
+ }
+ else if (left == SQLP_NULL || right == SQLP_NULL) {
+ return SQLP_NULL;
+ }
+ else {
+ return SQLP_BOOL;
+ }
- switch ( nptr->oper ) {
- /* Arithmetical */
- case SQLP_ADD:
- case SQLP_SUBTR:
- case SQLP_MLTP:
- case SQLP_DIV:
- if ( left == SQLP_S || right == SQLP_S ) {
- append_error ("Arithmetical operation with strings is not allowed\n" );
- return -1;
- } else if ( left == SQLP_NULL || right == SQLP_NULL ) {
- return SQLP_NULL;
- } else if ( left == SQLP_I && right == SQLP_I && ( nptr->oper == SQLP_ADD ||
- nptr->oper == SQLP_SUBTR || nptr->oper == SQLP_MLTP ) )
- {
- return SQLP_I;
- } else {
- return SQLP_D;
- }
- break;
+ case SQLP_ISNULL:
+ case SQLP_NOTNULL:
+ return SQLP_BOOL;
- /* Comparison */
- /* Operators valid for all type */
- case SQLP_EQ:
- case SQLP_NE:
- if ( ( left == SQLP_S && ( right == SQLP_I || right == SQLP_D ) ) ||
- ( right == SQLP_S && ( left == SQLP_I || left == SQLP_D ) ) )
- {
- append_error ("Comparison between string and number is not allowed\n" );
- return -1;
- } else if ( left == SQLP_NULL || right == SQLP_NULL ) {
- return SQLP_NULL;
- } else {
- return SQLP_BOOL;
- }
- /* Operators valid for numbers */
- case SQLP_LT:
- case SQLP_LE:
- case SQLP_GT:
- case SQLP_GE:
- if ( left == SQLP_S || right == SQLP_S ) {
- append_error ("Comparison '%s' between strings not allowed\n",
- sqpOperatorName(nptr->oper) );
- return -1;
- } else if ( left == SQLP_NULL || right == SQLP_NULL ) {
- return SQLP_NULL;
- } else {
- return SQLP_BOOL;
- }
- /* Operator valid for string */
- case SQLP_MTCH:
- if ( left == SQLP_I || left == SQLP_D || right == SQLP_I || right == SQLP_D ) {
- append_error ("Match (~) between numbers not allowed\n" );
- return -1;
- } else if ( left == SQLP_NULL || right == SQLP_NULL ) {
- return SQLP_NULL;
- } else {
- return SQLP_BOOL;
- }
+ /* Logical */
+ case SQLP_AND:
+ if (left == SQLP_NULL || right == SQLP_NULL) {
+ return SQLP_NULL;
+ }
+ else {
+ return SQLP_BOOL;
+ }
+ case SQLP_OR:
+ if (left == SQLP_NULL && right == SQLP_NULL) {
+ return SQLP_NULL;
+ }
+ else {
+ return SQLP_BOOL;
+ }
+ case SQLP_NOT:
+ /* sub node stored on the right side */
+ if (right == SQLP_NULL) {
+ return SQLP_NULL;
+ }
+ else {
+ return SQLP_BOOL;
+ }
- case SQLP_ISNULL:
- case SQLP_NOTNULL:
- return SQLP_BOOL;
+ default:
+ append_error("Unknown operator %d\n", nptr->oper);
+ return -1;
+ }
+ }
- /* Logical */
- case SQLP_AND:
- if ( left == SQLP_NULL || right == SQLP_NULL ) {
- return SQLP_NULL;
- } else {
- return SQLP_BOOL;
- }
- case SQLP_OR:
- if ( left == SQLP_NULL && right == SQLP_NULL ) {
- return SQLP_NULL;
- } else {
- return SQLP_BOOL;
- }
- case SQLP_NOT:
- /* sub node stored on the right side */
- if ( right == SQLP_NULL ) {
- return SQLP_NULL;
- } else {
- return SQLP_BOOL;
- }
-
- default:
- append_error ("Unknown operator %d\n", nptr->oper);
- return -1;
- }
- }
-
- return -1; /* Not reached */
+ return -1; /* Not reached */
}
More information about the grass-commit
mailing list