📄 swq.c
字号:
{ if( tokens[*tokens_consumed+1] != NULL && (strcasecmp(tokens[*tokens_consumed+1],"LIKE") == 0 || strcasecmp(tokens[*tokens_consumed+1],"ILIKE") == 0) ) { *tokens_consumed += 1; return SWQ_NOTLIKE; } else if( tokens[*tokens_consumed+1] != NULL && strcasecmp(tokens[*tokens_consumed+1],"IN") == 0 ) { *tokens_consumed += 1; return SWQ_NOTIN; } else return SWQ_NOT; } if( strcasecmp(token,"<=") == 0 ) return SWQ_LE; if( strcasecmp(token,">=") == 0 ) return SWQ_GE; if( strcasecmp(token,"=") == 0 ) return SWQ_EQ; if( strcasecmp(token,"!=") == 0 ) return SWQ_NE; if( strcasecmp(token,"<>") == 0 ) return SWQ_NE; if( strcasecmp(token,"<") == 0 ) return SWQ_LT; if( strcasecmp(token,">") == 0 ) return SWQ_GT; if( strcasecmp(token,"LIKE") == 0 ) return SWQ_LIKE; if( strcasecmp(token,"ILIKE") == 0 ) return SWQ_LIKE; if( strcasecmp(token,"IN") == 0 ) return SWQ_IN; if( strcasecmp(token,"IS") == 0 ) { if( tokens[*tokens_consumed+1] == NULL ) return SWQ_UNKNOWN; else if( strcasecmp(tokens[*tokens_consumed+1],"NULL") == 0 ) { *tokens_consumed += 1; return SWQ_ISNULL; } else if( strcasecmp(tokens[*tokens_consumed+1],"NOT") == 0 && tokens[*tokens_consumed+2] != NULL && strcasecmp(tokens[*tokens_consumed+2],"NULL") == 0 ) { *tokens_consumed += 2; return SWQ_ISNOTNULL; } else return SWQ_UNKNOWN; } return SWQ_UNKNOWN;}/************************************************************************//* swq_identify_field() *//************************************************************************/static int swq_identify_field( const char *token, swq_field_list *field_list, swq_field_type *this_type, int *table_id ){ int i; char table_name[128]; const char *field_token = token; int tables_enabled; if( field_list->table_count > 0 && field_list->table_ids != NULL ) tables_enabled = TRUE; else tables_enabled = FALSE;/* -------------------------------------------------------------------- *//* Parse out table name if present, and table support enabled. *//* -------------------------------------------------------------------- */ table_name[0] = '\0'; if( tables_enabled && strchr(token, '.') != NULL ) { int dot_offset = (int)(strchr(token,'.') - token); if( dot_offset < sizeof(table_name) ) { strncpy( table_name, token, dot_offset ); table_name[dot_offset] = '\0'; field_token = token + dot_offset + 1; } }/* -------------------------------------------------------------------- *//* Search for matching field. *//* -------------------------------------------------------------------- */ for( i = 0; i < field_list->count; i++ ) { int t_id = 0; if( strcasecmp( field_list->names[i], field_token ) != 0 ) continue; /* Do the table specifications match? */ if( tables_enabled ) { t_id = field_list->table_ids[i]; if( table_name[0] != '\0' && strcasecmp(table_name, field_list->table_defs[t_id].table_alias) != 0 ) continue;#ifdef notdef if( t_id != 0 && table_name[0] == '\0' ) continue;#endif } /* We have a match, return various information */ if( this_type != NULL ) { if( field_list->types != NULL ) *this_type = field_list->types[i]; else *this_type = SWQ_OTHER; } if( table_id != NULL ) *table_id = t_id; if( field_list->ids == NULL ) return i; else return field_list->ids[i]; }/* -------------------------------------------------------------------- *//* No match, return failure. *//* -------------------------------------------------------------------- */ if( this_type != NULL ) *this_type = SWQ_OTHER; if( table_id != NULL ) *table_id = 0; return -1;}/************************************************************************//* swq_parse_in_list() *//* *//* Parse the argument list to the IN predicate. Might be used *//* something like: *//* *//* WHERE color IN ('Red', 'Green', 'Blue') *//************************************************************************/static char *swq_parse_in_list( char **tokens, int *tokens_consumed ){ int i, text_off = 2; char *result; if( tokens[*tokens_consumed] == NULL || strcasecmp(tokens[*tokens_consumed],"(") != 0 ) { sprintf( swq_error, "IN argument doesn't start with '('." ); return NULL; } *tokens_consumed += 1; /* Establish length of all tokens plus separators. */ for( i = *tokens_consumed; tokens[i] != NULL && strcasecmp(tokens[i],")") != 0; i++ ) { text_off += strlen(tokens[i]) + 1; } result = (char *) SWQ_MALLOC(text_off); /* Actually capture all the arguments. */ text_off = 0; while( tokens[*tokens_consumed] != NULL && strcasecmp(tokens[*tokens_consumed],")") != 0 ) { strcpy( result + text_off, tokens[*tokens_consumed] ); text_off += strlen(tokens[*tokens_consumed]) + 1; *tokens_consumed += 1; if( strcasecmp(tokens[*tokens_consumed],",") != 0 && strcasecmp(tokens[*tokens_consumed],")") != 0 ) { sprintf( swq_error, "Contents of IN predicate missing comma or closing bracket." ); SWQ_FREE( result ); return NULL; } else if( strcasecmp(tokens[*tokens_consumed],",") == 0 ) *tokens_consumed += 1; } /* add final extra terminating zero char */ result[text_off] = '\0'; if( tokens[*tokens_consumed] == NULL ) { sprintf( swq_error, "Contents of IN predicate missing closing bracket." ); SWQ_FREE( result ); return NULL; } *tokens_consumed += 1; return result;}/************************************************************************//* swq_subexpr_compile() *//************************************************************************/static const char *swq_subexpr_compile( char **tokens, swq_field_list *field_list, swq_expr **expr_out, int *tokens_consumed ){ swq_expr *op; const char *error; int op_code = 0; *tokens_consumed = 0; *expr_out = NULL; if( tokens[0] == NULL || tokens[1] == NULL ) { sprintf( swq_error, "Not enough tokens to complete expression." ); return swq_error; } op = (swq_field_op *) SWQ_MALLOC(sizeof(swq_field_op)); memset( op, 0, sizeof(swq_field_op) ); op->field_index = -1; if( strcmp(tokens[0],"(") == 0 ) { int sub_consumed = 0; error = swq_subexpr_compile( tokens + 1, field_list, (swq_expr **) &(op->first_sub_expr), &sub_consumed ); if( error != NULL ) { swq_expr_free( op ); return error; } if( strcmp(tokens[sub_consumed+1],")") != 0 ) { swq_expr_free( op ); sprintf(swq_error,"Unclosed brackets, or incomplete expression."); return swq_error; } *tokens_consumed += sub_consumed + 2; /* If we are at the end of the tokens, we should return our subnode */ if( tokens[*tokens_consumed] == NULL || strcmp(tokens[*tokens_consumed],")") == 0 ) { *expr_out = (swq_expr *) op->first_sub_expr; op->first_sub_expr = NULL; swq_expr_free( op ); return NULL; } } else if( strcasecmp(tokens[0],"NOT") == 0 ) { /* do nothing, the NOT will be collected as the operation */ } else { op->field_index = swq_identify_field( tokens[*tokens_consumed], field_list, &(op->field_type), &(op->table_index) ); if( op->field_index < 0 ) { swq_expr_free( op ); sprintf( swq_error, "Failed to identify field:" ); strncat( swq_error, tokens[*tokens_consumed], sizeof(swq_error) - strlen(swq_error) - 1 ); return swq_error; } (*tokens_consumed)++; } /* ** Identify the operation. */ if( tokens[*tokens_consumed] == NULL || tokens[*tokens_consumed+1] == NULL) { sprintf( swq_error, "Not enough tokens to complete expression." ); return swq_error; } op->operation = swq_identify_op( tokens, tokens_consumed ); if( op->operation == SWQ_UNKNOWN ) { swq_expr_free( op ); sprintf( swq_error, "Failed to identify operation:" ); strncat( swq_error, tokens[*tokens_consumed], sizeof(swq_error) - strlen(swq_error) - 1 ); return swq_error; } if( SWQ_OP_IS_LOGICAL( op->operation ) && op->first_sub_expr == NULL && op->operation != SWQ_NOT ) { swq_expr_free( op ); strcpy( swq_error, "Used logical operation with non-logical operand."); return swq_error; } if( op->field_index != -1 && op->field_type == SWQ_STRING && (op->operation != SWQ_EQ && op->operation != SWQ_NE && op->operation != SWQ_LIKE && op->operation != SWQ_NOTLIKE && op->operation != SWQ_IN && op->operation != SWQ_NOTIN && op->operation != SWQ_ISNULL && op->operation != SWQ_ISNOTNULL )) { /* NOTE: the use of names[] here is wrong. We should be looking up the field that matches op->field_index and op->table_index */ sprintf( swq_error, "Attempt to use STRING field `%s' with numeric comparison `%s'.", field_list->names[op->field_index], tokens[*tokens_consumed] ); swq_expr_free( op ); return swq_error; } (*tokens_consumed)++; /* ** Collect the second operand as a subexpression. */ if( SWQ_OP_IS_POSTUNARY(op->operation) ) { /* we don't need another argument. */ } else if( tokens[*tokens_consumed] == NULL ) { sprintf( swq_error, "Not enough tokens to complete expression." ); return swq_error; } else if( SWQ_OP_IS_LOGICAL( op->operation ) ) { int sub_consumed = 0; error = swq_subexpr_compile( tokens + *tokens_consumed, field_list, (swq_expr **) &(op->second_sub_expr), &sub_consumed ); if( error != NULL ) { swq_expr_free( op ); return error; } *tokens_consumed += sub_consumed; } /* The IN predicate has a complex argument syntax. */ else if( op->operation == SWQ_IN || op->operation == SWQ_NOTIN ) { op->string_value = swq_parse_in_list( tokens, tokens_consumed ); if( op->string_value == NULL ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -