surrealdb / surrealdb

A scalable, distributed, collaborative, document-graph database, for the realtime web
https://surrealdb.com
Other
27.03k stars 866 forks source link

Bug: `The field 'myanylist[*]' already exists` #4894

Open gouvinb opened 2 days ago

gouvinb commented 2 days ago

Describe the bug

Dumps the database contents to a file when array type is present is incorrect or import not work when a <field>[*] (generated by a dump) is present.

Steps to reproduce

I have an SQL file with the following contents :

-- ------------------------------
-- OPTION
-- ------------------------------

OPTION IMPORT;

-- ------------------------------
-- TABLE: mytable
-- ------------------------------

DEFINE TABLE mytable TYPE NORMAL SCHEMAFULL PERMISSIONS NONE;

DEFINE FIELD _id ON mytable TYPE string ASSERT $value != NONE PERMISSIONS FULL;
DEFINE FIELD myliteral ON mytable TYPE { percent: int } ASSERT $value != NONE PERMISSIONS FULL;
DEFINE FIELD mystr ON mytable FLEXIBLE TYPE string ASSERT $value != NONE PERMISSIONS FULL;
DEFINE FIELD myanylist ON mytable FLEXIBLE TYPE array<any> PERMISSIONS FULL;

DEFINE INDEX _id ON mytable FIELDS _id UNIQUE;

-- ------------------------------
-- TABLE DATA: mytable
-- ------------------------------

I use this code to import it when the file exists:

pub async fn init_db() -> Result<(), surrealdb::Error> {
    match DB.connect::<Mem>(()).await {
        Ok(_) => {
            match DB
                .use_ns(if cfg!(debug_assertions) { "dev_ns" } else { "prod_ns" })
                .use_db("mydb")
                .await
            {
                Ok(_) => import_db().await,
                Err(err) => Err(err),
            }
        },
        Err(err) => Err(err),
    }
}

async fn import_db() -> Result<(), surrealdb::Error> {
    if Path::new(DB_PATH).exists() {
        DB.import(DB_PATH).await
    } else {
        // ...
    }
}

When my application is terminated, I save my changes with this code:

pub async fn save_db() -> Result<(), surrealdb::Error> {
    match DB.export(DB_PATH).await {
        Ok(_) => {
            info!("Database save into `{DB_PATH}`.");
            Ok(())
        }
        Err(err) => Err(err)
    }
}

and the following file is generated:

-- ------------------------------
-- OPTION
-- ------------------------------

OPTION IMPORT;

-- ------------------------------
-- TABLE: mytable
-- ------------------------------

DEFINE TABLE mytable TYPE NORMAL SCHEMAFULL PERMISSIONS NONE;

DEFINE FIELD _id ON mytable TYPE string ASSERT $value != NONE PERMISSIONS FULL;
DEFINE FIELD myliteral ON mytable TYPE { percent: int } ASSERT $value != NONE PERMISSIONS FULL;
DEFINE FIELD mystr ON mytable FLEXIBLE TYPE string ASSERT $value != NONE PERMISSIONS FULL;
DEFINE FIELD myanylist ON mytable FLEXIBLE TYPE array PERMISSIONS FULL;
DEFINE FIELD myanylist ON mytable FLEXIBLE TYPE any PERMISSIONS FULL;

DEFINE INDEX _id ON mytable FIELDS _id UNIQUE;

-- ------------------------------
-- TABLE DATA: mytable
-- ------------------------------

The instruction related to myanylist has been split into 2 instructions, making it impossible to import this file with the same code as above. The error message was: The field ‘myanylist[*]’ already exists.

The behaviour is the same with any changed to object.

Expected behaviour

Un fichier exporté devrait pouvoir être importer par la même application

SurrealDB version

surrealdb = { version = "2.0", features = ["kv-mem"] }

Contact Details

No response

Is there an existing issue for this?

Code of Conduct

suleimanas commented 1 day ago

same issue i had to redefine <field>[*] with overwrite