4
4
#include < string.h>
5
5
#include < stdlib.h>
6
6
#include " catalog/catname.h"
7
+ #include " utils/numeric.h"
7
8
8
9
#include " type.h"
9
10
#include " extern.h"
@@ -648,7 +649,7 @@ output_statement(char * stmt, int mode)
648
649
%type <str> def_elem def_list definition def_name def_type DefineStmt
649
650
%type <str> opt_instead event event_object OptStmtMulti OptStmtBlock
650
651
%type <str> OptStmtList RuleStmt opt_column opt_name oper_argtypes
651
- %type <str> MathOp RemoveFuncStmt aggr_argtype
652
+ %type <str> MathOp RemoveFuncStmt aggr_argtype for_update_clause
652
653
%type <str> RemoveAggrStmt remove_type RemoveStmt ExtendStmt RecipeStmt
653
654
%type <str> RemoveOperStmt RenameStmt all_Op user_valid_clause
654
655
%type <str> VariableSetStmt var_value zone_value VariableShowStmt
@@ -2611,9 +2612,18 @@ opt_of: OF columnList { $$ = make2_str(make1_str("of"), $2); }
2611
2612
SelectStmt : SELECT opt_unique res_target_list2
2612
2613
result from_clause where_clause
2613
2614
group_clause having_clause
2614
- union_clause sort_clause
2615
+ union_clause sort_clause for_update_clause
2615
2616
{
2616
- $$ = cat2_str(cat5_str(cat5_str(make1_str(" select" ), $2 , $3 , $4 , $5 ), $6 , $7 , $8 , $9 ), $10 );
2617
+ $$ = cat3_str(cat5_str(cat5_str(make1_str(" select" ), $2 , $3 , $4 , $5 ), $6 , $7 , $8 , $9 ), $10 , $11 );
2618
+ if (strlen($11 ) > 0 )
2619
+ {
2620
+ if (strlen($9 ) > 0 )
2621
+ yyerror (" SELECT FOR UPDATE is not allowed with UNION clause" );
2622
+ if (strlen($7 ) > 0 )
2623
+ yyerror (" SELECT FOR UPDATE is not allowed with GROUP BY clause" );
2624
+ if (strlen($6 ) > 0 )
2625
+ yyerror (" SELECT FOR UPDATE is not allowed with HAVING clause" );
2626
+ }
2617
2627
}
2618
2628
;
2619
2629
@@ -2721,6 +2731,20 @@ having_clause: HAVING a_expr
2721
2731
| /* EMPTY*/ { $$ = make1_str(" " ); }
2722
2732
;
2723
2733
2734
+ for_update_clause :
2735
+ FOR UPDATE
2736
+ {
2737
+ $$ = make1_str(" for update" );
2738
+ }
2739
+ | FOR UPDATE OF va_list
2740
+ {
2741
+ $$ = cat2_str(make1_str(" for update of" ), $4 );
2742
+ }
2743
+ | /* EMPTY */
2744
+ {
2745
+ $$ = make1_str(" " );
2746
+ }
2747
+ ;
2724
2748
2725
2749
/* ****************************************************************************
2726
2750
*
@@ -2897,8 +2921,7 @@ generic: ident { $$ = $1; }
2897
2921
2898
2922
/* SQL92 numeric data types
2899
2923
* Check FLOAT() precision limits assuming IEEE floating types.
2900
- * Provide rudimentary DECIMAL() and NUMERIC() implementations
2901
- * by checking parameters and making sure they match what is possible with INTEGER.
2924
+ * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
2902
2925
* - thomas 1997-09-18
2903
2926
*/
2904
2927
Numeric : FLOAT opt_float
@@ -2945,20 +2968,20 @@ opt_float: '(' Iconst ')'
2945
2968
2946
2969
opt_numeric : ' (' Iconst ' ,' Iconst ' )'
2947
2970
{
2948
- if (atol($2 ) != 9 ) {
2949
- sprintf (errortext, make1_str( " NUMERIC precision %s must be 9 " ) , $2);
2971
+ if (atol($2 ) < 1 || atol( $2 ) > NUMERIC_MAX_PRECISION ) {
2972
+ sprintf (errortext, " NUMERIC precision %s must be between 1 and %d " , $2 , NUMERIC_MAX_PRECISION );
2950
2973
yyerror (errortext);
2951
2974
}
2952
- if (atol($4 ) != 0 ) {
2953
- sprintf (errortext, " NUMERIC scale %s must be zero " , $4 );
2975
+ if (atol($4 ) < 0 || atol( $4 ) > atol ($ 2 ) ) {
2976
+ sprintf (errortext, " NUMERIC scale %s must be between 0 and precision %s " , $4 , $ 2 );
2954
2977
yyerror (errortext);
2955
2978
}
2956
2979
$$ = cat3_str(make2_str(make1_str(" (" ), $2 ), make1_str(" ," ), make2_str($4 , make1_str(" )" )));
2957
2980
}
2958
2981
| ' (' Iconst ' )'
2959
2982
{
2960
- if (atol($2 ) != 9 ) {
2961
- sprintf (" NUMERIC precision %s must be 9 " ,$ 2 );
2983
+ if (atol($2 ) < 1 || atol( $2 ) > NUMERIC_MAX_PRECISION ) {
2984
+ sprintf (errortext, " NUMERIC precision %s must be between 1 and %d " , $ 2 , NUMERIC_MAX_PRECISION );
2962
2985
yyerror (errortext);
2963
2986
}
2964
2987
$$ = make3_str(make1_str(" (" ), $2 , make1_str(" )" ));
@@ -2971,22 +2994,22 @@ opt_numeric: '(' Iconst ',' Iconst ')'
2971
2994
2972
2995
opt_decimal : ' (' Iconst ' ,' Iconst ' )'
2973
2996
{
2974
- if (atol($2 ) != 9 ) {
2975
- sprintf (errortext, " DECIMAL precision %s exceeds implementation limit of 9" , $2 );
2997
+ if (atol($2 ) < 1 || atol($2 ) > NUMERIC_MAX_PRECISION) {
2998
+ sprintf (errortext, " NUMERIC precision %s must be between 1 and %d" , $2 , NUMERIC_MAX_PRECISION);
2999
+ yyerror (errortext);
3000
+ }
3001
+ if (atol($4 ) < 0 || atol($4 ) > atol ($2 )) {
3002
+ sprintf (errortext, " NUMERIC scale %s must be between 0 and precision %s" , $4 , $2 );
2976
3003
yyerror (errortext);
2977
3004
}
2978
- if (atol($4 ) != 0 ) {
2979
- sprintf (errortext, " DECIMAL scale %s must be zero" ,$4 );
2980
- yyerror (errortext);
2981
- }
2982
3005
$$ = cat3_str(make2_str(make1_str(" (" ), $2 ), make1_str(" ," ), make2_str($4 , make1_str(" )" )));
2983
3006
}
2984
3007
| ' (' Iconst ' )'
2985
3008
{
2986
- if (atol($2 ) != 9 ) {
2987
- sprintf (errortext, " DECIMAL precision %s exceeds implementation limit of 9 " ,$ 2 );
2988
- yyerror (errortext);
2989
- }
3009
+ if (atol($2 ) < 1 || atol( $2 ) > NUMERIC_MAX_PRECISION ) {
3010
+ sprintf (errortext, " NUMERIC precision %s must be between 1 and %d " , $ 2 , NUMERIC_MAX_PRECISION );
3011
+ yyerror (errortext);
3012
+ }
2990
3013
$$ = make3_str(make1_str(" (" ), $2 , make1_str(" )" ));
2991
3014
}
2992
3015
| /* EMPTY*/
0 commit comments