Repository: edgedb/edgedb

Issue:
std::sequence default  value gets lost in migration
After a series of migrations the default value for std::sequence is lost and an INSERT without an explicit value complains about a missing value for the required property.

<!-- Please search existing issues to avoid creating duplicates. -->
- EdgeDB Version: 1.0b2.dev5500+g2f67186c8-2021030200~focal.nightly
- OS Version: Linux 5.8.0-44-generic #50~20.04.1-Ubuntu SMP Wed Feb 10 21:07:30 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Steps to Reproduce:

```bash
#!/usr/bin/env bash

set -ex

cd `mktemp --directory`
mkdir -p dbschema/migrations

edgedb server init --nightly bug

echo 'module default {
	type Exercise {
		required property name -> str {
			constraint exclusive;
		}
	}
	type Workout {
		required property started_at -> datetime {
			default := datetime_current();
			constraint exclusive;
		}
	}
	type Set_ {
		required link exercise -> Exercise;
		required link workout -> Workout;
		required property index -> int16 {
			constraint min_value(0);
		}
		required property weight -> float32;
		required property reps -> int16;
		required property completed -> bool {
			default := false;
		}

		constraint exclusive on ( (.index, .workout) );
	}
};' > dbschema/schema.esdl
yes | edgedb -I bug create-migration
edgedb -I bug migrate

echo 'module default {
	type Exercise {
		required property name -> str {
			constraint exclusive;
		}
	}
	type Workout {
		multi link sets := .<workout[IS Set_];
		required property started_at -> datetime {
			default := datetime_current();
			constraint exclusive;
		}
	}
	type Set_ {
		required link exercise -> Exercise;
		required link workout -> Workout;
		required property index -> int16 {
			constraint min_value(0);
		}
		required property weight -> float32;
		required property reps -> int16;
		required property completed -> bool {
			default := false;
		}

		constraint exclusive on ( (.index, .workout) );
	}
};' > dbschema/schema.esdl
yes | edgedb -I bug create-migration
edgedb -I bug migrate

echo 'module default {
	type Exercise {
		required property name -> str {
			constraint exclusive;
		}
	}
	type Workout {
		required property started_at -> datetime {
			default := datetime_current();
			constraint exclusive;
		}
		multi link sets -> Set_ {
			constraint exclusive;
		}
	}

	scalar type SetIndex extending sequence;

	type Set_ {
		link workout := .<sets[IS Workout];
		required link exercise -> Exercise;
		required property index -> SetIndex {
			constraint exclusive;
			constraint min_value(0);
		};
		required property weight -> float32;
		required property reps -> int16;
		required property completed -> bool {
			default := false;
		};
	}
};' > dbschema/schema.esdl
yes | edgedb -I bug create-migration
edgedb -I bug migrate

edgedb -I bug query '
INSERT Set_ {
	exercise := (INSERT Exercise {name := "Squat"}),
	workout := (INSERT Workout),
	weight := 1,
	reps := 2,
};'

# edgedb error: request error: ERROR: MissingRequiredError: missing value for required property 'index' of object type 'default::Set_'
```


Discussion:

Resolving patch:
diff --git a/edb/pgsql/delta.py b/edb/pgsql/delta.py
--- a/edb/pgsql/delta.py
+++ b/edb/pgsql/delta.py
@@ -2369,7 +2369,7 @@ def get_pointer_default(self, ptr, schema, context):
             else:
                 default_value = common.quote_literal(
                     str(default))
-        elif ptr.get_target(schema).issubclass(
+        elif (tgt := ptr.get_target(schema)) and tgt.issubclass(
                 schema, schema.get('std::sequence')):
             # TODO: replace this with a generic scalar type default
             #       using std::nextval().
@@ -2381,13 +2381,8 @@ def get_pointer_default(self, ptr, schema, context):
         return default_value
 
     def alter_pointer_default(self, pointer, schema, context):
-        default = self.get_resolved_attribute_value(
-            'default',
-            schema=schema,
-            context=context,
-        )
-        if default:
-            default_value = self.get_pointer_default(pointer, schema, context)
+        default_value = self.get_pointer_default(pointer, schema, context)
+        if default_value:
             source_ctx = context.get_ancestor(
                 s_sources.SourceCommandContext, self)
             alter_table = source_ctx.op.get_alter_table(


Test patch:
diff --git a/tests/test_edgeql_ddl.py b/tests/test_edgeql_ddl.py
--- a/tests/test_edgeql_ddl.py
+++ b/tests/test_edgeql_ddl.py
@@ -1229,6 +1229,27 @@ async def test_edgeql_ddl_28(self):
             };
         """)
 
+    async def test_edgeql_ddl_sequence_01(self):
+        await self.con.execute("""
+            SET MODULE test;
+            CREATE TYPE Foo {
+                CREATE REQUIRED PROPERTY index -> std::int64;
+            };
+        """)
+
+        await self.con.execute("""
+            CREATE SCALAR TYPE ctr EXTENDING std::sequence;
+            ALTER TYPE Foo {
+                ALTER PROPERTY index {
+                    SET TYPE ctr;
+                };
+            };
+        """)
+
+        await self.con.execute("""
+            INSERT Foo;
+        """)
+
     async def test_edgeql_ddl_abstract_link_01(self):
         await self.con.execute("""
             CREATE ABSTRACT LINK test::test_link;