summaryrefslogtreecommitdiff
path: root/sql/sql_parse.cc
diff options
context:
space:
mode:
authorunknown <anozdrin@mysql.com>2005-12-07 17:17:42 +0300
committerunknown <anozdrin@mysql.com>2005-12-07 17:17:42 +0300
commit943edab9a545c3a7bb3c55542b77f073ea21e91a (patch)
tree763144b950b19c3f90be07331782b4e4629cfc1e /sql/sql_parse.cc
parent9c8773f56338ad22419f8bb4587f935850814b9b (diff)
parent6b2f13098a59d9ad520828dca4cb63da8c86b5e3 (diff)
downloadmariadb-git-943edab9a545c3a7bb3c55542b77f073ea21e91a.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/alik/Documents/AllProgs/MySQL/devel/5.0-sp-vars-merge-2 mysql-test/r/sp.result: Auto merged mysql-test/t/sp.test: Auto merged sql/field.cc: Auto merged sql/item.cc: Auto merged sql/item.h: Auto merged sql/mysql_priv.h: Auto merged sql/sql_parse.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/sp_head.cc: Merge.
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r--sql/sql_parse.cc328
1 files changed, 4 insertions, 324 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 6a453407cd0..4e36c517869 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5770,9 +5770,10 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
buf, "TIMESTAMP");
}
- if (!(new_field= new_create_field(thd, field_name, type, length, decimals,
- type_modifier, default_value, on_update_value,
- comment, change, interval_list, cs, uint_geom_type)))
+ if (!(new_field= new create_field()) ||
+ new_field->init(thd, field_name, type, length, decimals, type_modifier,
+ default_value, on_update_value, comment, change,
+ interval_list, cs, uint_geom_type))
DBUG_RETURN(1);
lex->create_list.push_back(new_field);
@@ -5780,327 +5781,6 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
DBUG_RETURN(0);
}
-/*****************************************************************************
-** Create field definition for create
-** Return 0 on failure, otherwise return create_field instance
-******************************************************************************/
-
-create_field *
-new_create_field(THD *thd, char *field_name, enum_field_types type,
- char *length, char *decimals,
- uint type_modifier,
- Item *default_value, Item *on_update_value,
- LEX_STRING *comment,
- char *change, List<String> *interval_list, CHARSET_INFO *cs,
- uint uint_geom_type)
-{
- register create_field *new_field;
- uint sign_len, allowed_type_modifier=0;
- ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
- DBUG_ENTER("new_create_field");
-
- if (!(new_field=new create_field()))
- DBUG_RETURN(NULL);
- new_field->field=0;
- new_field->field_name=field_name;
- new_field->def= default_value;
- new_field->flags= type_modifier;
- new_field->unireg_check= (type_modifier & AUTO_INCREMENT_FLAG ?
- Field::NEXT_NUMBER : Field::NONE);
- new_field->decimals= decimals ? (uint)atoi(decimals) : 0;
- if (new_field->decimals >= NOT_FIXED_DEC)
- {
- my_error(ER_TOO_BIG_SCALE, MYF(0), new_field->decimals, field_name,
- NOT_FIXED_DEC-1);
- DBUG_RETURN(NULL);
- }
-
- new_field->sql_type=type;
- new_field->length=0;
- new_field->change=change;
- new_field->interval=0;
- new_field->pack_length= new_field->key_length= 0;
- new_field->charset=cs;
- new_field->geom_type= (Field::geometry_type) uint_geom_type;
-
- new_field->comment=*comment;
- /*
- Set flag if this field doesn't have a default value
- */
- if (!default_value && !(type_modifier & AUTO_INCREMENT_FLAG) &&
- (type_modifier & NOT_NULL_FLAG) && type != FIELD_TYPE_TIMESTAMP)
- new_field->flags|= NO_DEFAULT_VALUE_FLAG;
-
- if (length && !(new_field->length= (uint) atoi(length)))
- length=0; /* purecov: inspected */
- sign_len=type_modifier & UNSIGNED_FLAG ? 0 : 1;
-
- switch (type) {
- case FIELD_TYPE_TINY:
- if (!length) new_field->length=MAX_TINYINT_WIDTH+sign_len;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case FIELD_TYPE_SHORT:
- if (!length) new_field->length=MAX_SMALLINT_WIDTH+sign_len;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case FIELD_TYPE_INT24:
- if (!length) new_field->length=MAX_MEDIUMINT_WIDTH+sign_len;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case FIELD_TYPE_LONG:
- if (!length) new_field->length=MAX_INT_WIDTH+sign_len;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case FIELD_TYPE_LONGLONG:
- if (!length) new_field->length=MAX_BIGINT_WIDTH;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case FIELD_TYPE_NULL:
- break;
- case FIELD_TYPE_NEWDECIMAL:
- if (!length && !new_field->decimals)
- new_field->length= 10;
- if (new_field->length > DECIMAL_MAX_PRECISION)
- {
- my_error(ER_TOO_BIG_PRECISION, MYF(0), new_field->length, field_name,
- DECIMAL_MAX_PRECISION);
- DBUG_RETURN(NULL);
- }
- if (new_field->length < new_field->decimals)
- {
- my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
- DBUG_RETURN(NULL);
- }
- new_field->length=
- my_decimal_precision_to_length(new_field->length, new_field->decimals,
- type_modifier & UNSIGNED_FLAG);
- new_field->pack_length=
- my_decimal_get_binary_size(new_field->length, new_field->decimals);
- break;
- case MYSQL_TYPE_VARCHAR:
- /*
- Long VARCHAR's are automaticly converted to blobs in mysql_prepare_table
- if they don't have a default value
- */
- max_field_charlength= MAX_FIELD_VARCHARLENGTH;
- break;
- case MYSQL_TYPE_STRING:
- break;
- case FIELD_TYPE_BLOB:
- case FIELD_TYPE_TINY_BLOB:
- case FIELD_TYPE_LONG_BLOB:
- case FIELD_TYPE_MEDIUM_BLOB:
- case FIELD_TYPE_GEOMETRY:
- if (default_value) // Allow empty as default value
- {
- String str,*res;
- res=default_value->val_str(&str);
- if (res->length())
- {
- my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0),
- field_name); /* purecov: inspected */
- DBUG_RETURN(NULL);
- }
- new_field->def=0;
- }
- new_field->flags|=BLOB_FLAG;
- break;
- case FIELD_TYPE_YEAR:
- if (!length || new_field->length != 2)
- new_field->length=4; // Default length
- new_field->flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
- break;
- case FIELD_TYPE_FLOAT:
- /* change FLOAT(precision) to FLOAT or DOUBLE */
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- if (length && !decimals)
- {
- uint tmp_length=new_field->length;
- if (tmp_length > PRECISION_FOR_DOUBLE)
- {
- my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name);
- DBUG_RETURN(NULL);
- }
- else if (tmp_length > PRECISION_FOR_FLOAT)
- {
- new_field->sql_type=FIELD_TYPE_DOUBLE;
- new_field->length=DBL_DIG+7; // -[digits].E+###
- }
- else
- new_field->length=FLT_DIG+6; // -[digits].E+##
- new_field->decimals= NOT_FIXED_DEC;
- break;
- }
- if (!length && !decimals)
- {
- new_field->length = FLT_DIG+6;
- new_field->decimals= NOT_FIXED_DEC;
- }
- if (new_field->length < new_field->decimals &&
- new_field->decimals != NOT_FIXED_DEC)
- {
- my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
- DBUG_RETURN(NULL);
- }
- break;
- case FIELD_TYPE_DOUBLE:
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- if (!length && !decimals)
- {
- new_field->length = DBL_DIG+7;
- new_field->decimals=NOT_FIXED_DEC;
- }
- if (new_field->length < new_field->decimals &&
- new_field->decimals != NOT_FIXED_DEC)
- {
- my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
- DBUG_RETURN(NULL);
- }
- break;
- case FIELD_TYPE_TIMESTAMP:
- if (!length)
- new_field->length= 14; // Full date YYYYMMDDHHMMSS
- else if (new_field->length != 19)
- {
- /*
- We support only even TIMESTAMP lengths less or equal than 14
- and 19 as length of 4.1 compatible representation.
- */
- new_field->length=((new_field->length+1)/2)*2; /* purecov: inspected */
- new_field->length= min(new_field->length,14); /* purecov: inspected */
- }
- new_field->flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
- if (default_value)
- {
- /* Grammar allows only NOW() value for ON UPDATE clause */
- if (default_value->type() == Item::FUNC_ITEM &&
- ((Item_func*)default_value)->functype() == Item_func::NOW_FUNC)
- {
- new_field->unireg_check= (on_update_value?Field::TIMESTAMP_DNUN_FIELD:
- Field::TIMESTAMP_DN_FIELD);
- /*
- We don't need default value any longer moreover it is dangerous.
- Everything handled by unireg_check further.
- */
- new_field->def= 0;
- }
- else
- new_field->unireg_check= (on_update_value?Field::TIMESTAMP_UN_FIELD:
- Field::NONE);
- }
- else
- {
- /*
- If we have default TIMESTAMP NOT NULL column without explicit DEFAULT
- or ON UPDATE values then for the sake of compatiblity we should treat
- this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't
- have another TIMESTAMP column with auto-set option before this one)
- or DEFAULT 0 (in other cases).
- So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will
- replace this value by TIMESTAMP_DNUN_FIELD or NONE later when
- information about all TIMESTAMP fields in table will be availiable.
-
- If we have TIMESTAMP NULL column without explicit DEFAULT value
- we treat it as having DEFAULT NULL attribute.
- */
- new_field->unireg_check= (on_update_value ?
- Field::TIMESTAMP_UN_FIELD :
- (new_field->flags & NOT_NULL_FLAG ?
- Field::TIMESTAMP_OLD_FIELD:
- Field::NONE));
- }
- break;
- case FIELD_TYPE_DATE: // Old date type
- if (protocol_version != PROTOCOL_VERSION-1)
- new_field->sql_type=FIELD_TYPE_NEWDATE;
- /* fall trough */
- case FIELD_TYPE_NEWDATE:
- new_field->length=10;
- break;
- case FIELD_TYPE_TIME:
- new_field->length=10;
- break;
- case FIELD_TYPE_DATETIME:
- new_field->length=19;
- break;
- case FIELD_TYPE_SET:
- {
- if (interval_list->elements > sizeof(longlong)*8)
- {
- my_error(ER_TOO_BIG_SET, MYF(0), field_name); /* purecov: inspected */
- DBUG_RETURN(NULL);
- }
- new_field->pack_length= get_set_pack_length(interval_list->elements);
-
- List_iterator<String> it(*interval_list);
- String *tmp;
- while ((tmp= it++))
- new_field->interval_list.push_back(tmp);
- /*
- Set fake length to 1 to pass the below conditions.
- Real length will be set in mysql_prepare_table()
- when we know the character set of the column
- */
- new_field->length= 1;
- break;
- }
- case FIELD_TYPE_ENUM:
- {
- // Should be safe
- new_field->pack_length= get_enum_pack_length(interval_list->elements);
-
- List_iterator<String> it(*interval_list);
- String *tmp;
- while ((tmp= it++))
- new_field->interval_list.push_back(tmp);
- new_field->length= 1; // See comment for FIELD_TYPE_SET above.
- break;
- }
- case MYSQL_TYPE_VAR_STRING:
- DBUG_ASSERT(0); // Impossible
- break;
- case MYSQL_TYPE_BIT:
- {
- if (!length)
- new_field->length= 1;
- if (new_field->length > MAX_BIT_FIELD_LENGTH)
- {
- my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), field_name,
- MAX_BIT_FIELD_LENGTH);
- DBUG_RETURN(NULL);
- }
- new_field->pack_length= (new_field->length + 7) / 8;
- break;
- }
- case FIELD_TYPE_DECIMAL:
- DBUG_ASSERT(0); /* Was obsolete */
- }
-
- if (!(new_field->flags & BLOB_FLAG) &&
- ((new_field->length > max_field_charlength && type != FIELD_TYPE_SET &&
- type != FIELD_TYPE_ENUM &&
- (type != MYSQL_TYPE_VARCHAR || default_value)) ||
- (!new_field->length &&
- type != MYSQL_TYPE_STRING &&
- type != MYSQL_TYPE_VARCHAR && type != FIELD_TYPE_GEOMETRY)))
- {
- my_error((type == MYSQL_TYPE_VAR_STRING || type == MYSQL_TYPE_VARCHAR ||
- type == MYSQL_TYPE_STRING) ? ER_TOO_BIG_FIELDLENGTH :
- ER_TOO_BIG_DISPLAYWIDTH,
- MYF(0),
- field_name, max_field_charlength); /* purecov: inspected */
- DBUG_RETURN(NULL);
- }
- type_modifier&= AUTO_INCREMENT_FLAG;
- if ((~allowed_type_modifier) & type_modifier)
- {
- my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name);
- DBUG_RETURN(NULL);
- }
- DBUG_RETURN(new_field);
-}
-
/* Store position for column in ALTER TABLE .. ADD column */