[libgda] Correctly parse "NOT LIKE" and "NOT ILIKE" expressions
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda] Correctly parse "NOT LIKE" and "NOT ILIKE" expressions
- Date: Fri, 27 Jul 2012 12:08:39 +0000 (UTC)
commit 835c7d599124bd0a579ca59c5e3bf5a738beef7c
Author: Vivien Malerba <malerba gnome-db org>
Date: Fri Jul 27 12:45:50 2012 +0200
Correctly parse "NOT LIKE" and "NOT ILIKE" expressions
libgda/gda-statement.c | 6 ++++++
libgda/sql-parser/gda-sql-parser.c | 13 +++++++++----
libgda/sql-parser/gda-statement-struct-parts.c | 4 ++++
libgda/sql-parser/gda-statement-struct-parts.h | 5 ++++-
libgda/sql-parser/gda-statement-struct.c | 2 ++
libgda/sql-parser/parser.y | 4 +++-
libgda/sqlite/gda-sqlite-provider.c | 9 +++++++++
providers/firebird/parser.y | 3 ++-
providers/oracle/parser.y | 3 ++-
providers/reuseable/mysql/parser.y | 3 ++-
providers/reuseable/postgres/parser.y | 4 +++-
providers/skel-implementation/capi/parser.y | 3 ++-
12 files changed, 48 insertions(+), 11 deletions(-)
---
diff --git a/libgda/gda-statement.c b/libgda/gda-statement.c
index 46f2ab1..bac7768 100644
--- a/libgda/gda-statement.c
+++ b/libgda/gda-statement.c
@@ -1803,9 +1803,15 @@ default_render_operation (GdaSqlOperation *op, GdaSqlRenderingContext *context,
case GDA_SQL_OPERATOR_TYPE_LIKE:
str = g_strdup_printf ("%s LIKE %s", SQL_OPERAND (sql_list->data)->sql, SQL_OPERAND (sql_list->next->data)->sql);
break;
+ case GDA_SQL_OPERATOR_TYPE_NOTLIKE:
+ str = g_strdup_printf ("%s NOT LIKE %s", SQL_OPERAND (sql_list->data)->sql, SQL_OPERAND (sql_list->next->data)->sql);
+ break;
case GDA_SQL_OPERATOR_TYPE_ILIKE:
str = g_strdup_printf ("%s ILIKE %s", SQL_OPERAND (sql_list->data)->sql, SQL_OPERAND (sql_list->next->data)->sql);
break;
+ case GDA_SQL_OPERATOR_TYPE_NOTILIKE:
+ str = g_strdup_printf ("%s NOT ILIKE %s", SQL_OPERAND (sql_list->data)->sql, SQL_OPERAND (sql_list->next->data)->sql);
+ break;
case GDA_SQL_OPERATOR_TYPE_GT:
str = g_strdup_printf ("%s > %s", SQL_OPERAND (sql_list->data)->sql, SQL_OPERAND (sql_list->next->data)->sql);
break;
diff --git a/libgda/sql-parser/gda-sql-parser.c b/libgda/sql-parser/gda-sql-parser.c
index 94f3800..8393658 100644
--- a/libgda/sql-parser/gda-sql-parser.c
+++ b/libgda/sql-parser/gda-sql-parser.c
@@ -1033,7 +1033,7 @@ token_as_string (gchar *ptr, gint len)
return retval;
}
-static void
+static gboolean
handle_composed_2_keywords (GdaSqlParser *parser, GValue *retval, gint second, gint replacer);
/*
@@ -1514,8 +1514,11 @@ getToken (GdaSqlParser *parser)
handle_composed_2_keywords (parser, retval, L_LOOP, L_ENDLOOP);
else if (parser->priv->context->token_type == L_IS)
handle_composed_2_keywords (parser, retval, L_NULL, L_ISNULL);
- else if (parser->priv->context->token_type == L_NOT)
- handle_composed_2_keywords (parser, retval, L_NULL, L_NOTNULL);
+ else if (parser->priv->context->token_type == L_NOT) {
+ handle_composed_2_keywords (parser, retval, L_NULL, L_NOTNULL) ||
+ handle_composed_2_keywords (parser, retval, L_LIKE, L_NOTLIKE) ||
+ handle_composed_2_keywords (parser, retval, L_ILIKE, L_NOTILIKE);
+ }
else if (parser->priv->context->token_type == L_SIMILAR)
handle_composed_2_keywords (parser, retval, L_TO, L_SIMILAR);
@@ -1533,7 +1536,7 @@ getToken (GdaSqlParser *parser)
return retval;
}
-static void
+static gboolean
handle_composed_2_keywords (GdaSqlParser *parser, GValue *retval, gint second, gint replacer)
{
gint npushed, nmatched;
@@ -1547,11 +1550,13 @@ handle_composed_2_keywords (GdaSqlParser *parser, GValue *retval, gint second, g
newstr = g_strdup_printf ("%s %s", g_value_get_string (retval), g_value_get_string (v));
g_value_reset (retval);
g_value_take_string (retval, newstr);
+ return TRUE;
}
if (v) {
g_value_reset (v);
g_free (v);
}
+ return FALSE;
}
static GValue *
diff --git a/libgda/sql-parser/gda-statement-struct-parts.c b/libgda/sql-parser/gda-statement-struct-parts.c
index b656a70..9a5a37c 100644
--- a/libgda/sql-parser/gda-statement-struct-parts.c
+++ b/libgda/sql-parser/gda-statement-struct-parts.c
@@ -773,6 +773,10 @@ gda_sql_operation_operator_to_string (GdaSqlOperatorType op)
return "|";
case GDA_SQL_OPERATOR_TYPE_BITNOT:
return "~";
+ case GDA_SQL_OPERATOR_TYPE_NOTLIKE:
+ return "NOT LIKE";
+ case GDA_SQL_OPERATOR_TYPE_NOTILIKE:
+ return "NOT ILIKE";
default:
g_error ("Unhandled operator constant %d\n", op);
return NULL;
diff --git a/libgda/sql-parser/gda-statement-struct-parts.h b/libgda/sql-parser/gda-statement-struct-parts.h
index b1ded29..956feec 100644
--- a/libgda/sql-parser/gda-statement-struct-parts.h
+++ b/libgda/sql-parser/gda-statement-struct-parts.h
@@ -312,7 +312,10 @@ typedef enum {
GDA_SQL_OPERATOR_TYPE_BITAND,
GDA_SQL_OPERATOR_TYPE_BITOR,
GDA_SQL_OPERATOR_TYPE_BITNOT,
- GDA_SQL_OPERATOR_TYPE_ILIKE
+ GDA_SQL_OPERATOR_TYPE_ILIKE,
+
+ GDA_SQL_OPERATOR_TYPE_NOTLIKE,
+ GDA_SQL_OPERATOR_TYPE_NOTILIKE
} GdaSqlOperatorType;
/**
diff --git a/libgda/sql-parser/gda-statement-struct.c b/libgda/sql-parser/gda-statement-struct.c
index b6e4a1c..1094901 100644
--- a/libgda/sql-parser/gda-statement-struct.c
+++ b/libgda/sql-parser/gda-statement-struct.c
@@ -1052,7 +1052,9 @@ gda_sql_any_part_check_structure (GdaSqlAnyPart *node, GError **error)
case GDA_SQL_OPERATOR_TYPE_EQ:
case GDA_SQL_OPERATOR_TYPE_IS:
case GDA_SQL_OPERATOR_TYPE_LIKE:
+ case GDA_SQL_OPERATOR_TYPE_NOTLIKE:
case GDA_SQL_OPERATOR_TYPE_ILIKE:
+ case GDA_SQL_OPERATOR_TYPE_NOTILIKE:
case GDA_SQL_OPERATOR_TYPE_GT:
case GDA_SQL_OPERATOR_TYPE_LT:
case GDA_SQL_OPERATOR_TYPE_GEQ:
diff --git a/libgda/sql-parser/parser.y b/libgda/sql-parser/parser.y
index 16c4d8a..e87fe62 100644
--- a/libgda/sql-parser/parser.y
+++ b/libgda/sql-parser/parser.y
@@ -254,7 +254,7 @@ compose_multiple_compounds (GdaSqlStatementCompoundType ctype, GdaSqlStatement *
%left OR.
%left AND.
%right NOT.
-%left IS MATCH LIKE ILIKE IN ISNULL NOTNULL DIFF EQ.
+%left IS MATCH NOTLIKE LIKE NOTILIKE ILIKE IN ISNULL NOTNULL DIFF EQ.
%left BETWEEN.
%left GT LEQ LT GEQ.
%left REGEXP REGEXP_CI NOT_REGEXP NOT_REGEXP_CI.
@@ -824,6 +824,8 @@ expr(C) ::= expr(L) GT|LEQ|GEQ|LT(O) expr(R). {C = create_two_expr (string_to_op
expr(C) ::= expr(L) DIFF|EQ(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) LIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_LIKE, L, R);}
expr(C) ::= expr(L) ILIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_ILIKE, L, R);}
+expr(C) ::= expr(L) NOTLIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_NOTLIKE, L, R);}
+expr(C) ::= expr(L) NOTILIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_NOTILIKE, L, R);}
expr(C) ::= expr(L) REGEXP|REGEXP_CI|NOT_REGEXP|NOT_REGEXP_CI|SIMILAR(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) BETWEEN expr(R) AND expr(E). {GdaSqlOperation *cond;
C = gda_sql_expr_new (NULL);
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index 6236c80..bfada09 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -2018,6 +2018,15 @@ sqlite_render_operation (GdaSqlOperation *op, GdaSqlRenderingContext *context, G
case GDA_SQL_OPERATOR_TYPE_LIKE:
str = g_strdup_printf ("%s LIKE %s", SQL_OPERAND (sql_list->data)->sql, SQL_OPERAND (sql_list->next->data)->sql);
break;
+ case GDA_SQL_OPERATOR_TYPE_NOTLIKE:
+ str = g_strdup_printf ("%s NOT LIKE %s", SQL_OPERAND (sql_list->data)->sql, SQL_OPERAND (sql_list->next->data)->sql);
+ break;
+ case GDA_SQL_OPERATOR_TYPE_ILIKE:
+ case GDA_SQL_OPERATOR_TYPE_NOTILIKE:
+ g_set_error (error, GDA_STATEMENT_ERROR, GDA_STATEMENT_SYNTAX_ERROR,
+ "%s", _("ILIKE operation sot supported"));
+ goto out;
+ break;
case GDA_SQL_OPERATOR_TYPE_GT:
str = g_strdup_printf ("%s > %s", SQL_OPERAND (sql_list->data)->sql, SQL_OPERAND (sql_list->next->data)->sql);
break;
diff --git a/providers/firebird/parser.y b/providers/firebird/parser.y
index 1b50e1e..622296d 100644
--- a/providers/firebird/parser.y
+++ b/providers/firebird/parser.y
@@ -251,7 +251,7 @@ compose_multiple_compounds (GdaSqlStatementCompoundType ctype, GdaSqlStatement *
%left OR.
%left AND.
%right NOT.
-%left IS MATCH LIKE IN ISNULL NOTNULL DIFF EQ.
+%left IS MATCH NOTLIKE LIKE IN ISNULL NOTNULL DIFF EQ.
%left BETWEEN.
%left GT LEQ LT GEQ.
%left REGEXP REGEXP_CI NOT_REGEXP NOT_REGEXP_CI.
@@ -821,6 +821,7 @@ expr(C) ::= expr(L) CONCAT expr(R). {C = compose_multiple_expr (GDA_SQL_OPERATOR
expr(C) ::= expr(L) GT|LEQ|GEQ|LT(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) DIFF|EQ(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) LIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_LIKE, L, R);}
+expr(C) ::= expr(L) NOTLIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_NOTLIKE, L, R);}
expr(C) ::= expr(L) REGEXP|REGEXP_CI|NOT_REGEXP|NOT_REGEXP_CI|SIMILAR(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) BETWEEN expr(R) AND expr(E). {GdaSqlOperation *cond;
C = gda_sql_expr_new (NULL);
diff --git a/providers/oracle/parser.y b/providers/oracle/parser.y
index 739ec16..2c43450 100644
--- a/providers/oracle/parser.y
+++ b/providers/oracle/parser.y
@@ -251,7 +251,7 @@ compose_multiple_compounds (GdaSqlStatementCompoundType ctype, GdaSqlStatement *
%left OR.
%left AND.
%right NOT.
-%left IS MATCH LIKE IN ISNULL NOTNULL DIFF EQ.
+%left IS MATCH NOTLIKE LIKE IN ISNULL NOTNULL DIFF EQ.
%left BETWEEN.
%left GT LEQ LT GEQ.
%left REGEXP REGEXP_CI NOT_REGEXP NOT_REGEXP_CI.
@@ -821,6 +821,7 @@ expr(C) ::= expr(L) CONCAT expr(R). {C = compose_multiple_expr (GDA_SQL_OPERATOR
expr(C) ::= expr(L) GT|LEQ|GEQ|LT(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) DIFF|EQ(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) LIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_LIKE, L, R);}
+expr(C) ::= expr(L) NOTLIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_NOTLIKE, L, R);}
expr(C) ::= expr(L) REGEXP|REGEXP_CI|NOT_REGEXP|NOT_REGEXP_CI|SIMILAR(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) BETWEEN expr(R) AND expr(E). {GdaSqlOperation *cond;
C = gda_sql_expr_new (NULL);
diff --git a/providers/reuseable/mysql/parser.y b/providers/reuseable/mysql/parser.y
index e6d4a4f..8c98f4a 100644
--- a/providers/reuseable/mysql/parser.y
+++ b/providers/reuseable/mysql/parser.y
@@ -251,7 +251,7 @@ compose_multiple_compounds (GdaSqlStatementCompoundType ctype, GdaSqlStatement *
%left OR.
%left AND.
%right NOT.
-%left IS MATCH LIKE IN ISNULL NOTNULL DIFF EQ.
+%left IS MATCH NOTLIKE LIKE IN ISNULL NOTNULL DIFF EQ.
%left BETWEEN.
%left GT LEQ LT GEQ.
%left REGEXP REGEXP_CI NOT_REGEXP NOT_REGEXP_CI.
@@ -821,6 +821,7 @@ expr(C) ::= expr(L) CONCAT expr(R). {C = compose_multiple_expr (GDA_SQL_OPERATOR
expr(C) ::= expr(L) GT|LEQ|GEQ|LT(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) DIFF|EQ(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) LIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_LIKE, L, R);}
+expr(C) ::= expr(L) NOTLIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_NOTLIKE, L, R);}
expr(C) ::= expr(L) REGEXP|REGEXP_CI|NOT_REGEXP|NOT_REGEXP_CI|SIMILAR(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) BETWEEN expr(R) AND expr(E). {GdaSqlOperation *cond;
C = gda_sql_expr_new (NULL);
diff --git a/providers/reuseable/postgres/parser.y b/providers/reuseable/postgres/parser.y
index 478532a..ba05097 100644
--- a/providers/reuseable/postgres/parser.y
+++ b/providers/reuseable/postgres/parser.y
@@ -253,7 +253,7 @@ compose_multiple_compounds (GdaSqlStatementCompoundType ctype, GdaSqlStatement *
%left OR.
%left AND.
%right NOT.
-%left IS MATCH LIKE ILIKE IN ISNULL NOTNULL DIFF EQ.
+%left IS MATCH NOTLIKE LIKE NOTILIKE ILIKE IN ISNULL NOTNULL DIFF EQ.
%left BETWEEN.
%left GT LEQ LT GEQ.
%left REGEXP REGEXP_CI NOT_REGEXP NOT_REGEXP_CI.
@@ -824,6 +824,8 @@ expr(C) ::= expr(L) GT|LEQ|GEQ|LT(O) expr(R). {C = create_two_expr (string_to_op
expr(C) ::= expr(L) DIFF|EQ(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) LIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_LIKE, L, R);}
expr(C) ::= expr(L) ILIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_ILIKE, L, R);}
+expr(C) ::= expr(L) NOTLIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_NOTLIKE, L, R);}
+expr(C) ::= expr(L) NOTILIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_NOTILIKE, L, R);}
expr(C) ::= expr(L) REGEXP|REGEXP_CI|NOT_REGEXP|NOT_REGEXP_CI|SIMILAR(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) BETWEEN expr(R) AND expr(E). {GdaSqlOperation *cond;
C = gda_sql_expr_new (NULL);
diff --git a/providers/skel-implementation/capi/parser.y b/providers/skel-implementation/capi/parser.y
index 5941ce8..8003f5e 100644
--- a/providers/skel-implementation/capi/parser.y
+++ b/providers/skel-implementation/capi/parser.y
@@ -251,7 +251,7 @@ compose_multiple_compounds (GdaSqlStatementCompoundType ctype, GdaSqlStatement *
%left OR.
%left AND.
%right NOT.
-%left IS MATCH LIKE IN ISNULL NOTNULL DIFF EQ.
+%left IS MATCH NOTLIKE LIKE IN ISNULL NOTNULL DIFF EQ.
%left BETWEEN.
%left GT LEQ LT GEQ.
%left REGEXP REGEXP_CI NOT_REGEXP NOT_REGEXP_CI.
@@ -821,6 +821,7 @@ expr(C) ::= expr(L) CONCAT expr(R). {C = compose_multiple_expr (GDA_SQL_OPERATOR
expr(C) ::= expr(L) GT|LEQ|GEQ|LT(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) DIFF|EQ(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) LIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_LIKE, L, R);}
+expr(C) ::= expr(L) NOTLIKE expr(R). {C = create_two_expr (GDA_SQL_OPERATOR_TYPE_NOTLIKE, L, R);}
expr(C) ::= expr(L) REGEXP|REGEXP_CI|NOT_REGEXP|NOT_REGEXP_CI|SIMILAR(O) expr(R). {C = create_two_expr (string_to_op_type (O), L, R);}
expr(C) ::= expr(L) BETWEEN expr(R) AND expr(E). {GdaSqlOperation *cond;
C = gda_sql_expr_new (NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]