📄 swq.c
字号:
}/* -------------------------------------------------------------------- *//* Get the table name. Remove the '.' used to qualify it *//* relative to the datasource name if found. *//* -------------------------------------------------------------------- */ if( datasource != NULL && (*token)[0] != '.' ) { table = datasource; datasource = NULL; } else if( (*token)[0] == '.' ) { table = swq_strdup( (*token) + 1 ); SWQ_FREE( *token ); *token = swq_token( *input, input, is_literal ); } else { table = *token; *token = swq_token( *input, input, is_literal ); }/* -------------------------------------------------------------------- *//* Was an alias provided? *//* -------------------------------------------------------------------- */ if( *token != NULL && ! *is_literal && strcasecmp(*token,"ON") != 0 && strcasecmp(*token,"ORDER") != 0 && strcasecmp(*token,"WHERE") != 0 && strcasecmp(*token,"LEFT") != 0 && strcasecmp(*token,"JOIN") != 0 ) { alias = *token; *token = swq_token( *input, input, is_literal ); }/* -------------------------------------------------------------------- *//* Does this match an existing table definition? *//* -------------------------------------------------------------------- */ for( i = 0; i < select_info->table_count; i++ ) { swq_table_def *table_def = select_info->table_defs + i; if( datasource == NULL && alias == NULL && strcasecmp(table_def->table_alias,table) == 0 ) return i; if( datasource != NULL && table_def->data_source != NULL && strcasecmp(datasource,table_def->data_source) == 0 && strcasecmp(table,table_def->table_name) == 0 ) return i; }/* -------------------------------------------------------------------- *//* Add a new entry to the tables table. *//* -------------------------------------------------------------------- */ select_info->table_defs = swq_realloc( select_info->table_defs, sizeof(swq_table_def) * (select_info->table_count), sizeof(swq_table_def) * (select_info->table_count+1) );/* -------------------------------------------------------------------- *//* Populate the new entry. *//* -------------------------------------------------------------------- */ if( alias == NULL ) alias = swq_strdup( table ); select_info->table_defs[select_info->table_count].data_source = datasource; select_info->table_defs[select_info->table_count].table_name = table; select_info->table_defs[select_info->table_count].table_alias = alias; select_info->table_count++; return select_info->table_count - 1;}/************************************************************************//* swq_select_expand_wildcard() *//* *//* This function replaces the '*' in a "SELECT *" with the list *//* provided list of fields. Itis used by swq_select_parse(), *//* but may be called in advance by applications wanting the *//* "default" field list to be different than the full list of *//* fields. *//************************************************************************/const char *swq_select_expand_wildcard( swq_select *select_info, swq_field_list *field_list ){ int isrc;/* ==================================================================== *//* Check each pre-expansion field. *//* ==================================================================== */ for( isrc = 0; isrc < select_info->result_columns; isrc++ ) { const char *src_fieldname = select_info->column_defs[isrc].field_name; int itable, new_fields, i, iout; if( src_fieldname[strlen(src_fieldname)-1] != '*' ) continue; /* We don't want to expand COUNT(*) */ if( select_info->column_defs[isrc].col_func_name != NULL ) continue;/* -------------------------------------------------------------------- *//* Parse out the table name, verify it, and establish the *//* number of fields to insert from it. *//* -------------------------------------------------------------------- */ if( strcmp(src_fieldname,"*") == 0 ) { itable = -1; new_fields = field_list->count; } else if( strlen(src_fieldname) < 3 || src_fieldname[strlen(src_fieldname)-2] != '.' ) { sprintf( swq_error, "Ill formatted field definition '%s'.", src_fieldname ); return swq_error; } else { char *table_name = swq_strdup( src_fieldname ); table_name[strlen(src_fieldname)-2] = '\0'; for( itable = 0; itable < field_list->table_count; itable++ ) { if( strcasecmp(table_name, field_list->table_defs[itable].table_alias ) == 0 ) break; } if( itable == field_list->table_count ) { sprintf( swq_error, "Table %s not recognised from %s definition.", table_name, src_fieldname ); swq_free( table_name ); return swq_error; } swq_free( table_name ); /* count the number of fields in this table. */ new_fields = 0; for( i = 0; i < field_list->count; i++ ) { if( field_list->table_ids[i] == itable ) new_fields++; } }/* -------------------------------------------------------------------- *//* Reallocate the column list larger. *//* -------------------------------------------------------------------- */ SWQ_FREE( select_info->column_defs[isrc].field_name ); select_info->column_defs = (swq_col_def *) swq_realloc( select_info->column_defs, sizeof(swq_col_def) * select_info->result_columns, sizeof(swq_col_def) * (select_info->result_columns + new_fields - 1 ) );/* -------------------------------------------------------------------- *//* Push the old definitions that came after the one to be *//* replaced further up in the array. *//* -------------------------------------------------------------------- */ for( i = select_info->result_columns-1; i > isrc; i-- ) { memcpy( select_info->column_defs + i + new_fields - 1, select_info->column_defs + i, sizeof( swq_col_def ) ); } select_info->result_columns += (new_fields - 1 );/* -------------------------------------------------------------------- *//* Zero out all the stuff in the target column definitions. *//* -------------------------------------------------------------------- */ memset( select_info->column_defs + i, 0, new_fields * sizeof(swq_col_def) );/* -------------------------------------------------------------------- *//* Assign the selected fields. *//* -------------------------------------------------------------------- */ iout = isrc; for( i = 0; i < field_list->count; i++ ) { swq_col_def *def = select_info->column_defs + iout; int compose = itable != -1; /* skip this field if it isn't in the target table. */ if( itable != -1 && field_list->table_ids != NULL && itable != field_list->table_ids[i] ) continue; /* does this field duplicate an earlier one? */ if( field_list->table_ids != NULL && field_list->table_ids[i] != 0 && !compose ) { int other; for( other = 0; other < i; other++ ) { if( strcasecmp(field_list->names[i], field_list->names[other]) == 0 ) { compose = 1; break; } } } if( !compose ) def->field_name = swq_strdup( field_list->names[i] ); else { int itable = field_list->table_ids[i]; char *composed_name; const char *field_name = field_list->names[i]; const char *table_alias = field_list->table_defs[itable].table_alias; composed_name = (char *) swq_malloc(strlen(field_name)+strlen(table_alias)+2); sprintf( composed_name, "%s.%s", table_alias, field_name ); def->field_name = composed_name; } iout++; /* All the other table info will be provided by the later parse operation. */ } return NULL; } return NULL;}/************************************************************************//* swq_select_parse() *//************************************************************************/const char *swq_select_parse( swq_select *select_info, swq_field_list *field_list, int parse_flags ){ int i; const char *error; error = swq_select_expand_wildcard( select_info, field_list ); if( error != NULL ) return error;/* -------------------------------------------------------------------- *//* Identify field information. *//* -------------------------------------------------------------------- */ for( i = 0; i < select_info->result_columns; i++ ) { swq_col_def *def = select_info->column_defs + i; swq_field_type this_type; /* identify field */ def->field_index = swq_identify_field( def->field_name, field_list, &this_type, &(def->table_index) ); /* record field type */ def->field_type = this_type; /* identify column function if present */ if( def->col_func_name != NULL ) { if( strcasecmp(def->col_func_name,"AVG") == 0 ) def->col_func = SWQCF_AVG; else if( strcasecmp(def->col_func_name,"MIN") == 0 ) def->col_func = SWQCF_MIN; else if( strcasecmp(def->col_func_name,"MAX") == 0 ) def->col_func = SWQCF_MAX; else if( strcasecmp(def->col_func_name,"SUM") == 0 ) def->col_func = SWQCF_SUM; else if( strcasecmp(def->col_func_name,"COUNT") == 0 ) def->col_func = SWQCF_COUNT; else { def->col_func = SWQCF_CUSTOM; if( !(parse_flags & SWQP_ALLOW_UNDEFINED_COL_FUNCS) ) { sprintf( swq_error, "Unrecognised field function %s.", def->col_func_name ); return swq_error; } } if( (def->col_func == SWQCF_MIN || def->col_func == SWQCF_MAX || def->col_func == SWQCF_AVG || def->col_func == SWQCF_SUM) && this_type == SWQ_STRING ) { sprintf( swq_error, "Use of field function %s() on string field %s illegal.", def->col_func_name, def->field_name ); return swq_error; } } else def->col_func = SWQCF_NONE; if( def->field_index == -1 && def->col_func != SWQCF_COUNT ) { sprintf( swq_error, "Unrecognised field name %s.", def->field_name ); return swq_error; } }/* -------------------------------------------------------------------- *//* Check if we are producing a one row summary result or a set *//* of records. Generate an error if we get conflicting *//* indications. *//* -------------------------------------------------------------------- */ select_info->query_mode = -1; for( i = 0; i < select_info->result_columns; i++ ) { swq_col_def *def = select_info->column_defs + i; int this_indicator = -1; if( def->col_func == SWQCF_MIN || def->col_func == SWQCF_MAX || def->col_func == SWQCF_AVG || def->col_func == SWQCF_SUM || def->col_func == SWQCF_COUNT ) this_indicator = SWQM_SUMMARY_RECORD; else if( def->col_func == SWQCF_NONE ) { if( def->distinct_flag ) this_indicator = SWQM_DISTINCT_LIST; else this_indicator = SWQM_RECORDSET; } if( this_indicator != select_info->query_mode && this_indicator != -1 && select_info->query_mode != -1 ) { return "Field list implies mixture of regular recordset mode, summary mode or distinct field list mode."; } if( this_indicator != -1 ) select_info->query_mode = this_indicator; } if( select_info->result_columns > 1 && select_info->query_mode == SWQM_DISTINCT_LIST ) { return "SELECTing more than one DISTINCT field is a query not supported."; }/* -------------------------------------------------------------------- *//* Process column names in JOIN specs. *//* -------------------------------------------------------------------- */ for( i = 0; i < select_info->join_count; i++ ) { swq_join_def *def = select_info->join_defs + i; int table_id; /* identify primary field */ def->primary_field = swq_identify_field( def->primary_field_name, field_list, NULL, &table_id ); if( def->primary_field == -1 ) { sprintf( swq_error, "Unrecognised primary field %s in JOIN clause..", def->primary_field_name ); return swq_error; } if( table_id != 0 ) { sprintf( swq_error, "Currently the primary key must come from the primary table in\n" "JOIN, %s is not from the primary table
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -