📄 swq.c
字号:
&& 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.",
def->primary_field_name );
return swq_error;
}
/* identify secondary field */
def->secondary_field = swq_identify_field( def->secondary_field_name,
field_list, NULL,&table_id);
if( def->secondary_field == -1 )
{
sprintf( swq_error,
"Unrecognised secondary field %s in JOIN clause..",
def->primary_field_name );
return swq_error;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -