summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2005-11-13 19:12:05 +0000
committerTom Lane2005-11-13 19:12:05 +0000
commitc7d40ff35fe3f203d166e999da42e6e150859a36 (patch)
tree7601706ae3170cfcb113e345f8ee135e35b515b7
parent55b5a42b6a0408a6eff2aba35967914264fc5451 (diff)
Force the second argument of SUBSTRING(foo FOR bar) to be int4, to avoid
surprising results when it's some other numeric type. This doesn't solve the generic problem of surprising implicit casts to text, but it's a low-impact way of making sure this particular case behaves sanely. Per gripe from Harald Fuchs and subsequent discussion.
-rw-r--r--src/backend/parser/gram.y18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 766fe912d55..43f74fc011e 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.481 2004/12/31 22:00:27 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.481.4.1 2005/11/13 19:12:05 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -7137,9 +7137,10 @@ position_list:
* SQL9x defines a specific syntax for arguments to SUBSTRING():
* o substring(text from int for int)
* o substring(text from int) get entire string from starting point "int"
- * o substring(text from pattern) get entire string matching pattern
* o substring(text for int) get first "int" characters of string
- * We also want to implement generic substring functions which accept
+ * o substring(text from pattern) get entire string matching pattern
+ * o substring(text from pattern for escape) same with specified escape char
+ * We also want to support generic substring functions which accept
* the usual generic list of arguments. So we will accept both styles
* here, and convert the SQL9x style to the generic list for further
* processing. - thomas 2000-11-28
@@ -7151,6 +7152,7 @@ substr_list:
}
| a_expr substr_for substr_from
{
+ /* not legal per SQL99, but might as well allow it */
$$ = list_make3($1, $3, $2);
}
| a_expr substr_from
@@ -7159,10 +7161,18 @@ substr_list:
}
| a_expr substr_for
{
+ /*
+ * Since there are no cases where this syntax allows
+ * a textual FOR value, we forcibly cast the argument
+ * to int4. This is a kluge to avoid surprising results
+ * when the argument is, say, int8. It'd be better if
+ * there were not an implicit cast from int8 to text ...
+ */
A_Const *n = makeNode(A_Const);
n->val.type = T_Integer;
n->val.val.ival = 1;
- $$ = list_make3($1, (Node *)n, $2);
+ $$ = list_make3($1, (Node *) n,
+ makeTypeCast($2, SystemTypeName("int4")));
}
| expr_list
{