Repository: gluesql/gluesql (rust)

Issue:
DEFAULT column attribute support for CREATE TABLE
```sql
CREATE TABLE Foo (
  id INTEGER DEFAULT 1
);
```

For now, create sql query is accepted but not working.
Modification in [row.rs](https://github.com/gluesql/gluesql/blob/main/src/data/row.rs) is required.

Pull request description:
Implement DEFAULT column option support in CREATE TABLE
resolve #75 

Patch:
diff --git a/src/data/row.rs b/src/data/row.rs
index 412cfa4c..1f7f883b 100644
--- a/src/data/row.rs
+++ b/src/data/row.rs
@@ -58,21 +58,36 @@ impl Row {
                 let name = name.to_string();
 
                 let i = match columns.len() {
-                    0 => Ok(i),
-                    _ => columns
-                        .iter()
-                        .position(|target| target.value == name)
-                        .ok_or_else(|| RowError::LackOfRequiredColumn(name.clone())),
+                    0 => Some(i),
+                    _ => columns.iter().position(|target| target.value == name),
+                };
+
+                let default = options
+                    .iter()
+                    .find(|ColumnOptionDef { option, .. }| match option {
+                        ColumnOption::Default(_) => true,
+                        _ => false,
+                    });
+
+                let expr = match (i, default) {
+                    (Some(i), _) => values
+                        .get(i)
+                        .ok_or_else(|| RowError::LackOfRequiredValue(name.clone())),
+                    (
+                        None,
+                        Some(&ColumnOptionDef {
+                            option: ColumnOption::Default(ref expr),
+                            ..
+                        }),
+                    ) => Ok(expr),
+                    (None, _) => Err(RowError::LackOfRequiredColumn(name.clone())),
                 }?;
 
-                let literal = values
-                    .get(i)
-                    .ok_or_else(|| RowError::LackOfRequiredValue(name.clone()))?;
                 let nullable = options
                     .iter()
                     .any(|ColumnOptionDef { option, .. }| option == &ColumnOption::Null);
 
-                match literal {
+                match expr {
                     Expr::Value(literal) => Value::from_data_type(&data_type, nullable, literal),
                     Expr::Identifier(Ident { value, .. }) => Ok(Value::Str(value.clone())),
                     _ => Err(RowError::UnsupportedAstValueType.into()),


Test patch:
diff --git a/src/tests/default.rs b/src/tests/default.rs
new file mode 100644
index 00000000..7f10a707
--- /dev/null
+++ b/src/tests/default.rs
@@ -0,0 +1,43 @@
+use crate::*;
+
+pub fn default(mut tester: impl tests::Tester) {
+    use Value::*;
+
+    let test_cases = [
+        (
+            "CREATE TABLE Test (
+                id INTEGER DEFAULT 1,
+                num INTEGER,
+                flag BOOLEAN NULL DEFAULT false
+            )",
+            Payload::Create,
+        ),
+        ("INSERT INTO Test VALUES (8, 80, true);", Payload::Insert(1)),
+        ("INSERT INTO Test (num) VALUES (10);", Payload::Insert(1)),
+        (
+            "INSERT INTO Test (num, id) VALUES (20, 2);",
+            Payload::Insert(1),
+        ),
+        (
+            "INSERT INTO Test (num, flag) VALUES (30, NULL), (40, true);",
+            Payload::Insert(2),
+        ),
+        (
+            "SELECT * FROM Test;",
+            select!(
+                I64 I64 OptBool;
+                8   80  Some(true);
+                1   10  Some(false);
+                2   20  Some(false);
+                1   30  None;
+                1   40  Some(true)
+            ),
+        ),
+    ];
+
+    test_cases.iter().for_each(|(sql, expected)| {
+        let found = tester.run(sql).unwrap();
+
+        assert_eq!(expected, &found);
+    });
+}
diff --git a/src/tests/mod.rs b/src/tests/mod.rs
index f7ace23e..5789bfcb 100644
--- a/src/tests/mod.rs
+++ b/src/tests/mod.rs
@@ -2,6 +2,7 @@ pub mod aggregate;
 pub mod arithmetic;
 pub mod basic;
 pub mod blend;
+pub mod default;
 pub mod drop_table;
 pub mod error;
 pub mod filter;
@@ -45,6 +46,7 @@ macro_rules! generate_tests {
         glue!(join_blend, join::blend);
         glue!(migrate, migrate::migrate);
         glue!(nested_select, nested_select::nested_select);
+        glue!(default, default::default);
         glue!(nullable, nullable::nullable);
         glue!(nullable_text, nullable::nullable_text);
         glue!(ordering, ordering::ordering);