CPLString swq_expr_node::QuoteIfNecessary( const CPLString &osExpr, char chQuote ) { if( osExpr[0] == '_' ) return Quote(osExpr, chQuote); if( osExpr == "*" ) return osExpr; for( int i = 0; i < static_cast<int>(osExpr.size()); i++ ) { char ch = osExpr[i]; if( (!(isalnum(static_cast<int>(ch)) || ch == '_')) || ch == '.' ) { return Quote(osExpr, chQuote); } } if( swq_is_reserved_keyword(osExpr) ) { return Quote(osExpr, chQuote); } return osExpr; }
char *swq_expr_node::Unparse( swq_field_list *field_list, char chColumnQuote ) { CPLString osExpr; /* -------------------------------------------------------------------- */ /* Handle constants. */ /* -------------------------------------------------------------------- */ if( eNodeType == SNT_CONSTANT ) { if (is_null) return CPLStrdup("NULL"); if( field_type == SWQ_INTEGER || field_type == SWQ_BOOLEAN ) osExpr.Printf( "%d", int_value ); else if( field_type == SWQ_FLOAT ) { osExpr.Printf( "%.15g", float_value ); /* Make sure this is interpreted as a floating point value */ /* and not as an integer later */ if (strchr(osExpr, '.') == NULL && strchr(osExpr, 'e') == NULL && strchr(osExpr, 'E') == NULL) osExpr += '.'; } else { osExpr = string_value; Quote( osExpr ); } return CPLStrdup(osExpr); } /* -------------------------------------------------------------------- */ /* Handle columns. */ /* -------------------------------------------------------------------- */ if( eNodeType == SNT_COLUMN ) { if( field_index != -1 && table_index < field_list->table_count && table_index > 0 ) osExpr.Printf( "%s.%s", field_list->table_defs[table_index].table_name, field_list->names[field_index] ); else if( field_index != -1 ) osExpr.Printf( "%s", field_list->names[field_index] ); for( int i = 0; i < (int) osExpr.size(); i++ ) { char ch = osExpr[i]; if (!(isalnum((int)ch) || ch == '_')) { Quote( osExpr, chColumnQuote ); return CPLStrdup(osExpr.c_str()); } } if (swq_is_reserved_keyword(osExpr)) { Quote( osExpr, chColumnQuote ); return CPLStrdup(osExpr.c_str()); } /* The string is just alphanum and not a reserved SQL keyword, no needs to quote and escape */ return CPLStrdup(osExpr.c_str()); } /* -------------------------------------------------------------------- */ /* Operation - start by unparsing all the subexpressions. */ /* -------------------------------------------------------------------- */ std::vector<char*> apszSubExpr; int i; for( i = 0; i < nSubExprCount; i++ ) apszSubExpr.push_back( papoSubExpr[i]->Unparse(field_list, chColumnQuote) ); /* -------------------------------------------------------------------- */ /* Put things together in a fashion depending on the operator. */ /* -------------------------------------------------------------------- */ const swq_operation *poOp = swq_op_registrar::GetOperator( (swq_op) nOperation ); if( poOp == NULL ) { CPLAssert( FALSE ); return CPLStrdup(""); } switch( nOperation ) { // binary infix operators. case SWQ_OR: case SWQ_AND: case SWQ_EQ: case SWQ_NE: case SWQ_GT: case SWQ_LT: case SWQ_GE: case SWQ_LE: case SWQ_LIKE: case SWQ_ADD: case SWQ_SUBTRACT: case SWQ_MULTIPLY: case SWQ_DIVIDE: case SWQ_MODULUS: CPLAssert( nSubExprCount >= 2 ); if (papoSubExpr[0]->eNodeType == SNT_COLUMN || papoSubExpr[0]->eNodeType == SNT_CONSTANT) { osExpr += apszSubExpr[0]; } else { osExpr += "("; osExpr += apszSubExpr[0]; osExpr += ")"; } osExpr += " "; osExpr += poOp->osName; osExpr += " "; if (papoSubExpr[1]->eNodeType == SNT_COLUMN || papoSubExpr[1]->eNodeType == SNT_CONSTANT) { osExpr += apszSubExpr[1]; } else { osExpr += "("; osExpr += apszSubExpr[1]; osExpr += ")"; } if( nOperation == SWQ_LIKE && nSubExprCount == 3 ) osExpr += CPLSPrintf( " ESCAPE (%s)", apszSubExpr[2] ); break; case SWQ_NOT: CPLAssert( nSubExprCount == 1 ); osExpr.Printf( "NOT (%s)", apszSubExpr[0] ); break; case SWQ_ISNULL: CPLAssert( nSubExprCount == 1 ); osExpr.Printf( "%s IS NULL", apszSubExpr[0] ); break; case SWQ_IN: osExpr.Printf( "%s IN (", apszSubExpr[0] ); for( i = 1; i < nSubExprCount; i++ ) { if( i > 1 ) osExpr += ","; osExpr += "("; osExpr += apszSubExpr[i]; osExpr += ")"; } osExpr += ")"; break; case SWQ_BETWEEN: CPLAssert( nSubExprCount == 3 ); osExpr.Printf( "%s %s (%s) AND (%s)", apszSubExpr[0], poOp->osName.c_str(), apszSubExpr[1], apszSubExpr[2] ); break; default: // function style. osExpr.Printf( "%s(", poOp->osName.c_str() ); for( i = 0; i < nSubExprCount; i++ ) { if( i > 0 ) osExpr += ","; osExpr += "("; osExpr += apszSubExpr[i]; osExpr += ")"; } osExpr += ")"; break; } /* -------------------------------------------------------------------- */ /* cleanup subexpressions. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nSubExprCount; i++ ) CPLFree( apszSubExpr[i] ); return CPLStrdup( osExpr.c_str() ); }