Commit e701333b authored by monty@mashka.mysql.fi's avatar monty@mashka.mysql.fi

INSERT ... VALUES(DEFAULT)

parent b71b26d1
......@@ -34456,13 +34456,13 @@ provide an interactive user interfaces to the database.
@example
INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tbl_name [(col_name,...)]
VALUES (expression,...),(...),...
VALUES ((expression | DEFAULT),...),(...),...
or INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
or INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tbl_name
SET col_name=expression, col_name=expression, ...
SET col_name=(expression | DEFAULT), ...
@end example
......@@ -34492,6 +34492,11 @@ example, if you specify a column list that doesn't name all the columns in
the table, unnamed columns are set to their default values. Default value
assignment is described in @ref{CREATE TABLE, , @code{CREATE TABLE}}.
You can also use the keyword @code{DEFAULT} to set a column to it's
defaults value. (New in MySQL 4.0.3). This makes it easier to write
insert statements as you don't have to use a field-name list just because
you don't want to set a value for a few columns.
MySQL always has a default value for all fields. This is something
that is imposed on MySQL to be able to work with both transactional
and not transactional tables.
......@@ -50010,6 +50015,9 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@node News-4.0.3, News-4.0.2, News-4.0.x, News-4.0.x
@appendixsubsec Changes in release 4.0.3
@itemize @bullet
@item
Allow @code{DEFAULT} with @code{INSERT} statement.
@item
The startup parameters @code{myisam_max_extra_sort_file_size} and
@code{myisam_max_extra_sort_file_size} are now given in bytes, not megabytes.
@item
......@@ -19,3 +19,29 @@ insert into t1 values (0,"mysql a");
insert into t1 values (0,"r1manic");
insert into t1 values (0,"r1man");
drop table t1;
create table t1 (a int not null auto_increment, primary key (a), t timestamp, c char(10) default "hello");
insert into t1 values (default,default,default), (default,default,default), (4,0,"a"),(default,default,default);
select a,t>0,c from t1;
a t>0 c
1 1 hello
2 1 hello
4 0 a
5 1 hello
truncate table t1;
insert into t1 set a=default,t=default,c=default;
insert into t1 set a=default,t=default,c=default;
insert into t1 set a=4,t=0,c="a";
insert into t1 set a=default,t=default,c=default;
select a,t>0,c from t1;
a t>0 c
1 1 hello
2 1 hello
4 0 a
5 1 hello
drop table t1;
drop database if exists foo;
create database foo;
use foo;
create table t1 (c int);
insert into foo.t1 set foo.t1.c = '1';
drop database foo;
drop database if exists foo;
create database foo;
use foo;
create table b (c int);
insert into foo.b set foo.b.c = '1';
drop database foo;
......@@ -22,3 +22,29 @@ insert into t1 values (0,"mysql a");
insert into t1 values (0,"r1manic");
insert into t1 values (0,"r1man");
drop table t1;
#
# Test insert syntax
#
create table t1 (a int not null auto_increment, primary key (a), t timestamp, c char(10) default "hello");
insert into t1 values (default,default,default), (default,default,default), (4,0,"a"),(default,default,default);
select a,t>0,c from t1;
truncate table t1;
insert into t1 set a=default,t=default,c=default;
insert into t1 set a=default,t=default,c=default;
insert into t1 set a=4,t=0,c="a";
insert into t1 set a=default,t=default,c=default;
select a,t>0,c from t1;
drop table t1;
#
# Test of mysqld crash with fully qualified column names
#
drop database if exists foo;
create database foo;
use foo;
create table t1 (c int);
insert into foo.t1 set foo.t1.c = '1';
drop database foo;
#
# Test of mysqld crash with fully qualified column names
#
drop database if exists foo;
create database foo;
use foo;
create table b (c int);
insert into foo.b set foo.b.c = '1';
drop database foo;
......@@ -70,6 +70,10 @@ class Field {
virtual uint32 pack_length() const { return (uint32) field_length; }
virtual void reset(void) { bzero(ptr,pack_length()); }
virtual void reset_fields() {}
virtual void set_default()
{
memcpy(ptr, ptr + table->rec_buff_length, pack_length());
}
virtual bool binary() const { return 1; }
virtual bool zero_pack() const { return 1; }
virtual enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
......@@ -550,6 +554,10 @@ class Field_timestamp :public Field_num {
bool store_for_compare() { return 1; }
bool zero_pack() const { return 0; }
void set_time();
virtual void set_default()
{
set_time();
}
inline long get_timestamp()
{
#ifdef WORDS_BIGENDIAN
......
......@@ -383,12 +383,14 @@ void Item_datetime::make_field(Send_field *tmp_field)
init_make_field(tmp_field,FIELD_TYPE_DATETIME);
}
void Item_null::make_field(Send_field *tmp_field)
{
init_make_field(tmp_field,FIELD_TYPE_NULL);
tmp_field->length=4;
}
void Item_func::make_field(Send_field *tmp_field)
{
init_make_field(tmp_field, ((result_type() == STRING_RESULT) ?
......
......@@ -31,7 +31,7 @@ class Item {
enum Type {FIELD_ITEM,FUNC_ITEM,SUM_FUNC_ITEM,STRING_ITEM,
INT_ITEM,REAL_ITEM,NULL_ITEM,VARBIN_ITEM,
COPY_STR_ITEM,FIELD_AVG_ITEM,
COPY_STR_ITEM,FIELD_AVG_ITEM, DEFAULT_ITEM,
PROC_ITEM,COND_ITEM,REF_ITEM,FIELD_STD_ITEM, CONST_ITEM};
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
......@@ -285,6 +285,28 @@ class Item_string :public Item
unsigned int size_of() { return sizeof(*this);}
};
/* For INSERT ... VALUES (DEFAULT) */
class Item_default :public Item
{
public:
Item_default() { name= (char*) "DEFAULT"; }
enum Type type() const { return DEFAULT_ITEM; }
void make_field(Send_field *field) {}
bool save_in_field(Field *field)
{
field->set_default();
return 0;
}
virtual double val() { return 0.0; }
virtual longlong val_int() { return 0; }
virtual String *val_str(String *str) { return 0; }
bool basic_const_item() const { return 1; }
unsigned int size_of() { return sizeof(*this);}
};
/* for show tables */
class Item_datetime :public Item_string
......
......@@ -60,7 +60,7 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
if (grant_option &&
check_grant_all_columns(thd,INSERT_ACL,table))
return -1;
table->time_stamp=0; // This should be saved
table->time_stamp=0; // This is saved by caller
}
else
{ // Part field list
......@@ -178,7 +178,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
}
its.rewind ();
/*
** Fill in the given fields and dump it to the table file
Fill in the given fields and dump it to the table file
*/
info.records=info.deleted=info.copied=0;
......@@ -204,7 +204,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
thd->variables.bulk_insert_buff_size);
}
while ((values = its++))
while ((values= its++))
{
if (fields.elements || !value_count)
{
......@@ -367,7 +367,7 @@ static int last_uniq_key(TABLE *table,uint keynr)
/*
** Write a record to table with optional deleting of conflicting records
Write a record to table with optional deleting of conflicting records
*/
......@@ -461,9 +461,9 @@ int write_record(TABLE *table,COPY_INFO *info)
/******************************************************************************
Check that all fields with arn't null_fields are used
if DONT_USE_DEFAULT_FIELDS isn't defined use default value for not
set fields.
Check that all fields with arn't null_fields are used
If DONT_USE_DEFAULT_FIELDS isn't defined use default value for not set
fields.
******************************************************************************/
static int check_null_fields(THD *thd __attribute__((unused)),
......@@ -486,10 +486,8 @@ static int check_null_fields(THD *thd __attribute__((unused)),
}
/*****************************************************************************
** Handling of delayed inserts
**
** A thread is created for each table that one uses with the DELAYED
** attribute.
Handling of delayed inserts
A thread is created for each table that one uses with the DELAYED attribute.
*****************************************************************************/
class delayed_row :public ilink {
......@@ -1272,7 +1270,7 @@ bool delayed_insert::handle_inserts(void)
/***************************************************************************
** store records in INSERT ... SELECT *
Store records in INSERT ... SELECT *
***************************************************************************/
int
......@@ -1389,7 +1387,7 @@ bool select_insert::send_eof()
/***************************************************************************
** CREATE TABLE (SELECT) ...
CREATE TABLE (SELECT) ...
***************************************************************************/
int
......@@ -1487,7 +1485,7 @@ void select_create::abort()
/*****************************************************************************
** Instansiate templates
Instansiate templates
*****************************************************************************/
#ifdef __GNUC__
......
......@@ -519,7 +519,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
literal text_literal insert_ident order_ident
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
table_wild opt_pad no_in_expr expr_expr simple_expr no_and_expr
using_list expr_or_default
using_list expr_or_default set_expr_or_default
%type <item_list>
expr_list udf_expr_list when_list ident_list ident_list_arg
......@@ -2486,7 +2486,7 @@ ident_eq_list:
ident_eq_value;
ident_eq_value:
simple_ident equal expr
simple_ident equal expr_or_default
{
LEX *lex=Lex;
if (lex->field_list.push_back($1) ||
......@@ -2521,16 +2521,22 @@ opt_values:
| values;
values:
values ',' expr
values ',' expr_or_default
{
if (Lex->insert_list->push_back($3))
YYABORT;
}
| expr
{
if (Lex->insert_list->push_back($1))
YYABORT;
};
| expr_or_default
{
if (Lex->insert_list->push_back($1))
YYABORT;
}
;
expr_or_default:
expr { $$= $1;}
| DEFAULT {$$= new Item_default(); }
;
/* Update rows in a table */
......@@ -3257,12 +3263,12 @@ option_value:
{
Lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4)));
}
| internal_variable_name equal expr_or_default
| internal_variable_name equal set_expr_or_default
{
LEX *lex=Lex;
lex->var_list.push_back(new set_var(lex->option_type, $1, $3));
}
| '@' '@' opt_var_ident_type internal_variable_name equal expr_or_default
| '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default
{
LEX *lex=Lex;
lex->var_list.push_back(new set_var((enum_var_type) $3, $4, $6));
......@@ -3274,7 +3280,7 @@ option_value:
find_sys_var("transaction_isolation_num"),
new Item_int((int) $4)));
}
| CHAR_SYM SET opt_equal expr_or_default
| CHAR_SYM SET opt_equal set_expr_or_default
{
LEX *lex=Lex;
lex->var_list.push_back(new set_var(lex->option_type,
......@@ -3327,7 +3333,7 @@ text_or_password:
};
expr_or_default:
set_expr_or_default:
expr { $$=$1; }
| DEFAULT { $$=0; }
| ON { $$=new Item_string("ON",2); }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment