📄 swq.c
字号:
/* -------------------------------------------------------------------- *//* Allocate a big field list. *//* -------------------------------------------------------------------- */ swq_cols = (swq_col_def *) SWQ_MALLOC(sizeof(swq_col_def) * MAX_COLUMNS); memset( swq_cols, 0, sizeof(swq_col_def) * MAX_COLUMNS ); select_info->column_defs = swq_cols;/* -------------------------------------------------------------------- *//* Collect the field list, terminated by FROM keyword. *//* -------------------------------------------------------------------- */ token = swq_token( input, &input, &is_literal ); while( token != NULL && (is_literal || strcasecmp(token,"FROM") != 0) ) { char *next_token; int next_is_literal; if( select_info->result_columns == MAX_COLUMNS ) { SWQ_FREE( token ); swq_select_free( select_info ); sprintf( swq_error, "More than MAX_COLUMNS (%d) columns in SELECT statement.", MAX_COLUMNS ); return swq_error; } /* Ensure that we have a comma before fields other than the first. */ if( select_info->result_columns > 0 ) { if( strcasecmp(token,",") != 0 ) { sprintf( swq_error, "Missing comma after column %s in SELECT statement.", swq_cols[select_info->result_columns-1].field_name ); SWQ_FREE( token ); swq_select_free( select_info ); return swq_error; } SWQ_FREE( token ); token = swq_token( input, &input, &is_literal ); } /* read an extra token to check for brackets. */ select_info->result_columns++; next_token = swq_token( input, &input, &next_is_literal ); /* ** Handle function operators. */ if( !is_literal && !next_is_literal && next_token != NULL && strcasecmp(next_token,"(") == 0 ) { SWQ_FREE( next_token ); swq_cols[select_info->result_columns-1].col_func_name = token; token = swq_token( input, &input, &is_literal ); if( token != NULL && !is_literal && strcasecmp(token,"DISTINCT") == 0 ) { swq_cols[select_info->result_columns-1].distinct_flag = 1; SWQ_FREE( token ); token = swq_token( input, &input, &is_literal ); } swq_cols[select_info->result_columns-1].field_name = token; token = swq_token( input, &input, &is_literal ); if( token == NULL || strcasecmp(token,")") != 0 ) { if( token != NULL ) SWQ_FREE( token ); swq_select_free( select_info ); return "Missing closing bracket in field function."; } SWQ_FREE( token ); token = swq_token( input, &input, &is_literal ); } /* ** Handle simple field. */ else { if( token != NULL && !is_literal && strcasecmp(token,"DISTINCT") == 0 ) { swq_cols[select_info->result_columns-1].distinct_flag = 1; SWQ_FREE( token ); token = next_token; is_literal = next_is_literal; next_token = swq_token( input, &input, &next_is_literal ); } swq_cols[select_info->result_columns-1].field_name = token; token = next_token; is_literal = next_is_literal; } } /* make a columns_def list that is just the right size. */ select_info->column_defs = (swq_col_def *) SWQ_MALLOC(sizeof(swq_col_def) * select_info->result_columns); memcpy( select_info->column_defs, swq_cols, sizeof(swq_col_def) * select_info->result_columns ); SWQ_FREE( swq_cols );/* -------------------------------------------------------------------- *//* Collect the table name from the FROM clause. *//* -------------------------------------------------------------------- */ if( token == NULL || strcasecmp(token,"FROM") != 0 ) { strcpy( swq_error, "Missing FROM clause in SELECT statement." ); swq_select_free( select_info ); return swq_error; } SWQ_FREE( token ); token = swq_token( input, &input, &is_literal ); if( token == NULL ) { strcpy( swq_error, "Missing table name in FROM clause." ); swq_select_free( select_info ); return swq_error; } if( swq_parse_table_def( select_info, &is_literal, &token, &input) != 0 ) { swq_select_free( select_info ); return swq_error; }/* -------------------------------------------------------------------- *//* Do we have a LEFT JOIN (or just JOIN) clause? *//* -------------------------------------------------------------------- */ while( token != NULL && (strcasecmp(token,"LEFT") == 0 || strcasecmp(token,"JOIN") == 0) ) { swq_join_def *join_info; if( strcasecmp(token,"LEFT") == 0 ) { SWQ_FREE( token ); token = swq_token( input, &input, &is_literal ); if( token == NULL || strcasecmp(token,"JOIN") != 0 ) { strcpy( swq_error, "Missing JOIN keyword after LEFT." ); swq_select_free( select_info ); return swq_error; } } SWQ_FREE( token ); token = swq_token( input, &input, &is_literal ); /* Create join definition structure */ select_info->join_defs = (swq_join_def *) swq_realloc( select_info->join_defs, sizeof(swq_join_def) * (select_info->join_count), sizeof(swq_join_def) * (select_info->join_count+1) ); join_info = select_info->join_defs + select_info->join_count++; /* Parse out target table */ join_info->secondary_table = swq_parse_table_def( select_info, &is_literal, &token, &input); if( join_info->secondary_table < 0 ) { swq_select_free( select_info ); return swq_error; } /* Check for ON keyword */ if( token == NULL ) token = swq_token( input, &input, &is_literal ); if( token == NULL || strcasecmp(token,"ON") != 0 ) { swq_select_free( select_info ); strcpy( swq_error,"Corrupt JOIN clause, expecting ON keyword." ); return swq_error; } SWQ_FREE( token ); join_info->primary_field_name = swq_token( input, &input, &is_literal ); token = swq_token( input, &input, &is_literal ); if( token == NULL || strcasecmp(token,"=") != 0 ) { swq_select_free( select_info ); strcpy( swq_error,"Corrupt JOIN clause, expecting '=' condition."); return swq_error; } SWQ_FREE( token ); join_info->op = SWQ_EQ; join_info->secondary_field_name = swq_token( input, &input, &is_literal ); if( join_info->secondary_field_name == NULL ) { swq_select_free( select_info ); strcpy( swq_error,"Corrupt JOIN clause, missing secondary field."); return swq_error; } token = swq_token( input, &input, &is_literal ); }/* -------------------------------------------------------------------- *//* Do we have a WHERE clause? *//* -------------------------------------------------------------------- */ if( token != NULL && strcasecmp(token,"WHERE") == 0 ) { const char *where_base = input; while( *where_base == ' ' ) where_base++; SWQ_FREE( token ); token = swq_token( input, &input, &is_literal ); while( token != NULL ) { if( strcasecmp(token,"ORDER") == 0 && !is_literal ) { break; } if( token != NULL ) { SWQ_FREE( token ); token = swq_token( input, &input, &is_literal ); } } select_info->whole_where_clause = swq_strdup(where_base); if( input != NULL ) { if( token != NULL ) select_info->whole_where_clause[input - where_base - strlen(token)] = '\0'; else select_info->whole_where_clause[input - where_base] = '\0'; } }/* -------------------------------------------------------------------- *//* Parse ORDER BY clause. *//* -------------------------------------------------------------------- */ if( token != NULL && strcasecmp(token,"ORDER") == 0 ) { SWQ_FREE( token ); token = swq_token( input, &input, &is_literal ); if( token == NULL || strcasecmp(token,"BY") != 0 ) { if( token != NULL ) SWQ_FREE( token ); strcpy( swq_error, "ORDER BY clause missing BY keyword." ); swq_select_free( select_info ); return swq_error; } SWQ_FREE( token ); token = swq_token( input, &input, &is_literal ); while( token != NULL && (select_info->order_specs == 0 || strcasecmp(token,",") == 0) ) { swq_order_def *old_defs = select_info->order_defs; swq_order_def *def; if( select_info->order_specs != 0 ) { SWQ_FREE( token ); token = swq_token( input, &input, &is_literal ); } select_info->order_defs = (swq_order_def *) SWQ_MALLOC(sizeof(swq_order_def)*(select_info->order_specs+1)); if( old_defs != NULL ) { memcpy( select_info->order_defs, old_defs, sizeof(swq_order_def)*select_info->order_specs ); SWQ_FREE( old_defs ); } def = select_info->order_defs + select_info->order_specs; def->field_name = token; def->field_index = 0; def->ascending_flag = 1; token = swq_token( input, &input, &is_literal ); if( token != NULL && strcasecmp(token,"DESC") == 0 ) { SWQ_FREE( token ); token = swq_token( input, &input, &is_literal ); def->ascending_flag = 0; } else if( token != NULL && strcasecmp(token,"ASC") == 0 ) { SWQ_FREE( token ); token = swq_token( input, &input, &is_literal ); } select_info->order_specs++; } }/* -------------------------------------------------------------------- *//* If we have anything left it indicates an error! *//* -------------------------------------------------------------------- */ if( token != NULL ) { sprintf( swq_error, "Failed to parse SELECT statement, extra input at %s token.", token ); SWQ_FREE( token ); swq_select_free( select_info ); return swq_error; } *select_info_ret = select_info; return NULL;}/************************************************************************//* swq_parse_table_def() *//* *//* Supported table definition forms: *//* *//* <table_def> :== table_name *//* | 'data_source'.table_name *//* | table_name table_alias *//* | 'data_source'.table_name table_alias *//************************************************************************/static int swq_parse_table_def( swq_select *select_info, int *is_literal, char **token, char **input ){ int i; char *datasource = NULL; char *table = NULL; char *alias = NULL; if( *token == NULL ) *token = swq_token( *input, input, is_literal ); if( *token == NULL ) { strcpy( swq_error, "Corrupt table definition, insufficient tokens." ); return -1; } /* -------------------------------------------------------------------- *//* Do we have a datasource literal? *//* -------------------------------------------------------------------- */ if( *token != NULL && *is_literal ) { datasource = *token; *token = swq_token( *input, input, is_literal ); if( *token == NULL ) { *token = datasource; datasource = NULL; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -