📄 swq.c
字号:
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;
}
}
/* -------------------------------------------------------------------- */
/* 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -