1010 *
1111 *
1212 * IDENTIFICATION
13- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.47 1997/09/18 03:46:18 thomas Exp $
13+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.48 1997/09/20 16:11:42 thomas Exp $
1414 *
1515 * HISTORY
1616 * AUTHORDATEMAJOR EVENT
@@ -207,27 +207,31 @@ static char *FlattenStringList(List *list);
207207/* Keywords */
208208%tokenABORT_TRANS, ACL, ADD, AFTER, AGGREGATE, ALL, ALTER, ANALYZE,
209209AND, APPEND, ARCHIVE, ARCH_STORE, AS, ASC,
210- BACKWARD, BEFORE, BEGIN_TRANS, BETWEEN, BINARY,BOTH, BY,
210+ BACKWARD, BEFORE, BEGIN_TRANS, BETWEEN, BINARY, BY,
211211CAST, CHANGE, CHECK, CLOSE, CLUSTER, COLUMN,
212212COMMIT, CONSTRAINT, COPY, CREATE, CROSS, CURRENT, CURSOR,
213- DATABASE,DAYINTERVAL, DECLARE, DEFAULT, DELETE, DELIMITERS, DESC,
213+ DATABASE, DECLARE, DEFAULT, DELETE, DELIMITERS, DESC,
214214DISTINCT, DO, DROP, END_TRANS, EXISTS, EXTEND,
215- FETCH, FOR, FORWARD, FROM, FULL, FUNCTION, GRANT, GROUP, HAVING, HEAVY, HOURINTERVAL,
216- IN, INDEX, INHERITS, INNERJOIN, INSERT,INTERVAL, INSTEAD, INTO, IS, ISNULL,
217- JOIN, LANGUAGE,LEADING, LEFT, LIGHT, LISTEN, LOAD, LOCAL, MERGE, MINUTEINTERVAL, MONTHINTERVAL , MOVE,
215+ FETCH, FOR, FORWARD, FROM, FULL, FUNCTION, GRANT, GROUP, HAVING, HEAVY,
216+ IN, INDEX, INHERITS, INNERJOIN, INSERT, INSTEAD, INTO, IS, ISNULL,
217+ JOIN, LANGUAGE, LEFT, LIGHT, LISTEN, LOAD, LOCAL, MERGE, MOVE,
218218NATURAL, NEW, NONE, NOT, NOTHING, NOTIFY, NOTNULL,
219219OIDS, ON, OPERATOR, OPTION, OR, ORDER, OUTERJOIN,
220220PNULL, PRIVILEGES, PROCEDURE, PUBLIC, PURGE, P_TYPE,
221221RENAME, REPLACE, RESET, RETRIEVE, RETURNS, REVOKE, RIGHT, ROLLBACK, RULE,
222- SECONDINTERVAL, SELECT, SET, SETOF, SHOW, STDIN, STDOUT, STORE,
223- TABLE,TIME, TO, TRAILING , TRANSACTION, TRIGGER,
222+ SELECT, SET, SETOF, SHOW, STDIN, STDOUT, STORE,
223+ TABLE,TO , TRANSACTION, TRIGGER,
224224UNION, UNIQUE, UPDATE, USING, VACUUM, VALUES,
225- VERBOSE, VERSION, VIEW, WHERE, WITH, WORK, YEARINTERVAL, ZONE
225+ VERBOSE, VERSION, VIEW, WHERE, WITH, WORK
226226%tokenEXECUTE, RECIPE, EXPLAIN, LIKE, SEQUENCE
227227
228228/* SQL-92 support */
229+ %tokenINTERVAL, TIME, ZONE
230+ %tokenDAYINTERVAL, HOURINTERVAL, MINUTEINTERVAL, MONTHINTERVAL,
231+ SECONDINTERVAL, YEARINTERVAL
232+ %tokenBOTH, LEADING, TRAILING,
229233%tokenEXTRACT, POSITION, SUBSTRING, TRIM
230- %tokenDOUBLE, PRECISION
234+ %tokenDOUBLE, PRECISION, FLOAT
231235%tokenCHARACTER, VARYING
232236
233237/* Special keywords, not in the query language - see the "lex" file */
@@ -391,6 +395,17 @@ alter_clause: ADD opt_column columnDef
391395{
392396$$ = $3;
393397}
398+ | ADD '(' tableElementList ')'
399+ {
400+ ColumnDef *lp = lfirst($3);
401+
402+ if (length($3) != 1)
403+ elog(WARN,"ALTER TABLE/ADD() allows one column only",NULL);
404+ #ifdef PARSEDEBUG
405+ printf( "list has %d elements\n", length($3));
406+ #endif
407+ $$ = lp;
408+ }
394409| DROP opt_column Id
395410{elog(WARN,"ALTER TABLE/DROP COLUMN not yet implemented",NULL); }
396411| ALTER opt_column Id SET opt_default
@@ -2299,10 +2314,21 @@ nest_array_bounds:'[' ']' nest_array_bounds
22992314{ $$ = NIL; }
23002315;
23012316
2317+ /*
2318+ * typname handles types without trailing parens for size specification.
2319+ * Typename uses either typname or explicit txname(size).
2320+ * So, must handle float in both places. - thomas 1997-09-20
2321+ */
2322+
23022323typname: txname
23032324{
2304- char *tname = xlateSqlType($1) ;
2325+ char *tname;
23052326$$ = makeNode(TypeName);
2327+
2328+ if (!strcasecmp($1, "float"))
2329+ tname = xlateSqlType("float8");
2330+ else
2331+ tname = xlateSqlType($1);
23062332$$->name = tname;
23072333
23082334/* Is this the name of a complex type? If so, implement
@@ -2336,6 +2362,7 @@ txname: Id{ $$ = $1; }
23362362| INTERVAL interval_opts{ $$ = xlateSqlType("interval"); }
23372363| CHARACTER char_type{ $$ = $2; }
23382364| DOUBLE PRECISION{ $$ = xlateSqlType("float8"); }
2365+ | FLOAT{ $$ = xlateSqlType("float"); }
23392366;
23402367
23412368char_type: VARYING{ $$ = xlateSqlType("varchar"); }
@@ -2362,34 +2389,34 @@ Typename: typname opt_array_bounds
23622389$$ = $1;
23632390$$->arrayBounds = $2;
23642391if (!strcasecmp($1->name, "varchar"))
2365- {
23662392$$->typlen = 4 + 1;
2367- }
23682393}
23692394| txname '(' Iconst ')'
23702395{
23712396/*
2372- * This block gets hit when the parser is passed a query
2373- * which contains only spaces (e.g. from psql type " \g").
2374- * Let's check explicitly for a zero-length argument
2375- * here, and do nothing if so. This seems to fix the problem.
2376- * - thomas 1997-07-13
2397+ * The following implements CHAR() and VARCHAR().
2398+ * We do it here instead of the 'typname:' production
2399+ * because we don't want to allow arrays of VARCHAR().
2400+ * I haven't thought about whether that will work or not.
2401+ * - ay 6/95
2402+ * Also implements FLOAT() - thomas 1997-09-18
23772403 */
2378- if (strlen($1) > 0)
2379- {
2404+ $$ = makeNode(TypeName);
2405+ if (!strcasecmp($1, "float")) {
2406+ if ($3 < 1)
2407+ elog(WARN,"precision for '%s' type must be at least 1",$1);
2408+ else if ($3 <= 7)
2409+ $$->name = xlateSqlType("float4");
2410+ else if ($3 < 14)
2411+ $$->name = xlateSqlType("float8");
2412+ else
2413+ elog(WARN,"precision for '%s' type must be less than 14",$1);
23802414
2381- /*
2382- * The following implements char() and varchar().
2383- * We do it here instead of the 'typname:' production
2384- * because we don't want to allow arrays of varchar().
2385- * I haven't thought about whether that will work or not.
2386- * - ay 6/95
2387- */
2388- $$ = makeNode(TypeName);
2415+ } else {
23892416if (!strcasecmp($1, "char"))
2390- $$->name ="bpchar"; /* strdup ("bpchar"); */
2417+ $$->name =xlateSqlType ("bpchar");
23912418else if (!strcasecmp($1, "varchar"))
2392- $$->name ="varchar"; /* strdup ("varchar"); */
2419+ $$->name =xlateSqlType ("varchar");
23932420else
23942421yyerror("parse error");
23952422if ($3 < 1)
@@ -2408,7 +2435,6 @@ Typename: typname opt_array_bounds
24082435 * truncate where necessary
24092436 */
24102437$$->typlen = 4 + $3;
2411-
24122438}
24132439}
24142440;
@@ -3069,6 +3095,8 @@ static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
30693095
30703096/* xlateSqlType()
30713097 * Convert alternate type names to internal Postgres types.
3098+ * Do not convert "float", since that is handled elsewhere
3099+ * for FLOAT(p) syntax.
30723100 */
30733101static char *
30743102xlateSqlType(char *name)
@@ -3078,8 +3106,7 @@ xlateSqlType(char *name)
30783106return "int4"; /* strdup("int4") -- strdup leaks memory here */
30793107else if (!strcasecmp(name, "smallint"))
30803108return "int2";
3081- else if (!strcasecmp(name, "float") ||
3082- !strcasecmp(name, "real"))
3109+ else if (!strcasecmp(name, "real"))
30833110return "float8";
30843111else if (!strcasecmp(name, "interval"))
30853112return "timespan";